Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Lokal lesing av HAN - The Easy Way (TM)


Anbefalte innlegg

1 hour ago, petersv said:

@antonkristensen, har du prøvd https://www.npmjs.com/package/crc16 ?

Edit, denne ser bedre ut og sies er nettopp for MODBUS: https://www.npmjs.com/package/node-crc16

 

Har fått med meg denne, men hva i ****. skal man bruke resultatet fra den, er det noe comparison eller noe slikt for å få ut en bekreftelse, har skjønt det slik at man skal ikke regne med startflag, fcs(16bits) og endflag, er det slik at resultated fra crc skal være lik denne fcs-en ?

 

Lenke til kommentar
Del på andre sider

2 minutes ago, Hårek said:

Man får en pakke med data, inkludert 2 byte CRC. Da kjører man en CRC-sjekk på pakken minus 2 byte. Resultatet skal være likt med de 2 byte CRC.

 

ok så jeg kjører inn i crc hele bufferen eller må jeg slice-e bufferen slik at den dropper 1 og siste byte ?

 

har lest så mye forskjellig som forvirrer meg, noen plasser skal man droppe 1-3 byte og siste og noen plasser skal man droppe 1-3 byte og tredjesiste-siste byte, noen plasser skriver de at man skal regne hele pakken... ugh! haha! :D

Lenke til kommentar
Del på andre sider

7 minutter siden, OlavT skrev:

Hva er den enkleste måten å fikse en kabel med RJ45 kontakt i den ene enden? Finnes det en ferdig kabel med RJ45 plugg til å koble til HAN utgangen på AMS-måleren? Link?

 

Jeg tok en vanlig nettverkskabel og klippet av den ene enden. Så tok jeg tråd 1 og 2 og skrudde fast i terminalen på TSS721. 

  • Like 1
Lenke til kommentar
Del på andre sider

21 minutes ago, ZoRaC said:

 

Jeg tok en vanlig nettverkskabel og klippet av den ene enden. Så tok jeg tråd 1 og 2 og skrudde fast i terminalen på TSS721. 

 

Takk. Er det noen beskrivelse av hvor tråd 1 og 2 skal inn på TSS721 eller spiller det ingen rolle om de byttes rundt?

Lenke til kommentar
Del på andre sider

For de som er interesert...

Han1 nodejs mbus/han/whatever the protocol is Tool

 

Han1 skal fungere, om ikke så send meg gjerne melding...

Bruker raspberry pi og denne for de som er litt mere på koding/programmering skal ikke ha så vanskelig stund for å endre til usb f.eks.

Jeg har 3fas Kamstrup måler så den ble prioritert, rest kommer forhåpentligvis asap, vanskelig å jobbe på og lese ut data som ikke endrer seg...

 

dvs. den fungerer akkurat nå kun for Kamstrup måler...

Jobber på spreng med dette, har skrevet dette 2 ganger nå fra "scratch".

 

Håper på tilbakemeldinger og pull reqs og alt der inn i mellom :) 

Endret av antonkristensen
Nevne at jeg kjører kamstrup
Lenke til kommentar
Del på andre sider

Etter noen ukers venting har BKK endelig åpnet porten. Alt lå klart for integrasjon mot Homeseer og det fungerte med en gang. Har fulgt oppskriften i alternativ 1 + @Salvesen  sin løsning med cloudmqtt til mcsMQTT plugin. Også en stor takk til @petersv for informasjonsflyten!

 

Nå blir neste steg å få inn strømpriser, mener å ha sett noen løsninger på det her på forumet. 

  • Thanks 1
Lenke til kommentar
Del på andre sider

On 02/05/2018 at 20:39, Actibus said:

Takk for det, skjønte heller ikke at det ble trigget av besøk på serveren, så har nå bare lagt inn manuell trigging av handleRequest, for så å sende dataene via arduino plugin.

Puttet hele koden din inn i en API sketch fra Arduino Plugin, fungerer, men er jo med endel unødvendig som må ryddes vekk :)

arduino.thumb.PNG.3afb1d84cfad339733b3c8b5d66a9b79.PNG

 

Har du lyst til å dele Arduino koden du brukte for å få dette inn i arduinoplugin?

Lenke til kommentar
Del på andre sider

@GeneralVirus her er den, uten at jeg egentlig har fått ryddet noe mer opp i den, når noe fungerer så blir det fort bare værende sånn.

 

Opprett en tom API for NodeMcu dra plugin, lim inn dette før du kommer til: 

//************Do not change anything after Here*****************

etter loop() er ferdig

 

 


/*************************************************************
  Arduino to Homeseer 3 Plugin API written by Enigma Theatre.
   V1.0.0.146
 *                                                           *
 *************************************************************/
int FromHS[50];
boolean IsConnected = false;
//************************************************************


//**************Declare your variables here*******************

#include <EEPROM.h>
#include <ESP8266WiFi.h>
//JSON
#include <ESP8266HTTPClient.h>
//JSON SLUTT

static const byte EEPROM_INITIALIZED_MARKER = 0xF1; //Just a magic number

static const uint8_t HAN_RX_PIN     = 3;
int effekt;
int total;
short volt1;
short volt2;
short volt3;
short frekvens;
int forrigeEffekt;


static const int DATABUFFER_LENGTH = 256;
uint8_t data_buffer[DATABUFFER_LENGTH];
volatile int databuffer_pos;
volatile bool buffer_overflow;
volatile unsigned long databuffer_receive_time;
static unsigned long MINIMUM_TIME_BETWEEN_PACKETS = 1000L;

static const uint8_t SLIP_END     = 0xC0;
static const uint8_t SLIP_ESC     = 0xDB;
static const uint8_t SLIP_ESC_END = 0xDC;
static const uint8_t SLIP_ESC_ESC = 0xDD;

static const unsigned CRC16_XMODEM_POLY = 0x1021;

static const SerialConfig SERIAL_MODE = SERIAL_8N1;

void read_persistent_string(char* s, int max_length, int& adr)
{
  int i = 0;
  byte c;
  do {
    c = EEPROM.read(adr++);
    if (i<max_length)
    {
      s[i++] = static_cast<char>(c);
    }
  } while (c!=0);
  s[i] = 0;
}

void write_persistent_string(const char* s, size_t max_length, int& adr)
{
  for (int i=0; i<std::min(strlen(s), max_length); i++)
  {
    EEPROM.write(adr++, s[i]);
  }
  EEPROM.write(adr++, 0);
}

void serialEvent() {
  unsigned long now = millis();
  if (now<databuffer_receive_time || (now-databuffer_receive_time)>MINIMUM_TIME_BETWEEN_PACKETS)
  {
    databuffer_pos = 0;
    buffer_overflow = false;
    databuffer_receive_time = now;
  }

  uint8_t b;
  while (Serial.available()) {
    b = Serial.read();
    if (0==databuffer_pos && SLIP_END==b) //FRAME_END can be sent to force reset of buffer
    {
      continue;
    }
    
    if ((databuffer_pos+1) < DATABUFFER_LENGTH) //Room for one more byte?
    {
      //ESC ESC_END => END  (0xDB 0xDC => 0xC0)
      //ESC ESC_ESC => ESC  (0xDB 0xDD => 0xDB)
      if (databuffer_pos>0 && SLIP_ESC==data_buffer[databuffer_pos-1])
      {
        if (SLIP_ESC_END==b)
        {
          data_buffer[databuffer_pos-1] = SLIP_END;
          continue;
        }
        else if (SLIP_ESC_ESC==b)
        {
          //data_buffer[databuffer_pos-1] = SLIP_ESC; //Already has this value
          continue;
        }
      }

      data_buffer[databuffer_pos++] = b;
    }
    else
    {
      buffer_overflow = true;
    }
  }
}

char* toHex(char* buffer, unsigned int value)
{
  buffer[0]='0';
  buffer[1]='x';
  uint8_t length = value<256?2:4;
  for (uint8_t i=length; i>0; i--)
  {
    buffer[i+1] = ((value&0x000F)<=9?'0':'A'-10)+(value&0x000F);
    value = value >> 4;
  }
  buffer[length+2] = 0;
  return buffer;
}

void dumpHex(const uint8_t* data_buffer, int databuffer_pos, String& response, uint8_t start_pos, uint8_t length)
{
  char tmp_buffer[7];
  if(start_pos!=0)
  {
    response += "\n";
  }
  response.concat(toHex(tmp_buffer, start_pos));
  response += ":";
  for (int i=0; i<length && (start_pos+i)<databuffer_pos; i++)
  {
    response += " ";
    response.concat(toHex(tmp_buffer, data_buffer[start_pos+i]));
  }
}

unsigned int hexToInt(const uint8_t* data_buffer, int databuffer_pos, uint8_t start_pos)
{
  return ((start_pos+4)>databuffer_pos) ? 0 : data_buffer[start_pos+3]<<24 | data_buffer[start_pos+2]<<16 | data_buffer[start_pos+1]<<8 | data_buffer[start_pos];
}

unsigned short hexToShort(const uint8_t* data_buffer, int databuffer_pos, uint8_t start_pos)
{
  return ((start_pos+2)>databuffer_pos) ? 0 : data_buffer[start_pos+1]<<8 | data_buffer[start_pos];
}

boolean validCrc16(const uint8_t* data_buffer, int databuffer_pos, uint8_t content_start_pos, uint8_t content_length, uint8_t crc_start_pos)
{
  if ((content_start_pos+content_length)>databuffer_pos || (crc_start_pos+2)>databuffer_pos)
  {
    return false;
  }
  
  unsigned crc = 0;
  for (uint8_t i=0; i<content_length; i++)
  {
      crc ^= ((unsigned)data_buffer[content_start_pos+i]) << 8;
      for (uint8_t j=0; j<8; j++)
      {
        crc = crc&0x8000 ? (crc<<1)^CRC16_XMODEM_POLY : crc<<1;
      }
  }
  unsigned short actual_crc = hexToShort(data_buffer, databuffer_pos, crc_start_pos);
  return crc==actual_crc;
}

void handleRequest() {

  String response;
  dumpHex(data_buffer, databuffer_pos, response,  0, 16);
  response.concat(F("\tMålernummer: \""));
  for (uint8_t i=0; i<16; i++)
  {
    response.concat((char)data_buffer[i]);
  }
  response.concat(F("\""));

  dumpHex(data_buffer, databuffer_pos, response, 16,  4);
  response.concat(F("\tAkkumulert forbruk: "));
  response.concat(hexToInt(data_buffer, databuffer_pos, 16)/1000.0);
  response.concat(F("MWh"));
  total = hexToInt(data_buffer, databuffer_pos, 16)/1000.0;
 
  dumpHex(data_buffer, databuffer_pos, response, 20, 28);
  
  dumpHex(data_buffer, databuffer_pos, response, 48,  4);
  response.concat(F("\tForbruk: "));
  response.concat(hexToInt(data_buffer, databuffer_pos, 48));
  response.concat(F("W"));
  effekt = hexToInt(data_buffer, databuffer_pos, 48);
  

  dumpHex(data_buffer, databuffer_pos, response, 52, 12);

  dumpHex(data_buffer, databuffer_pos, response, 64,  2);
  response.concat(F("\tStrøm fase 1: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 64));
  response.concat(F("mA"));

  dumpHex(data_buffer, databuffer_pos, response, 66,  4);

  dumpHex(data_buffer, databuffer_pos, response, 70,  2);
  response.concat(F("\tStrøm fase 2: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 70));
  response.concat(F("mA"));

  dumpHex(data_buffer, databuffer_pos, response, 72,  6);

  dumpHex(data_buffer, databuffer_pos, response, 78,  2);
  response.concat(F("\tStrøm fase 3: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 78));
  response.concat(F("mA"));

  dumpHex(data_buffer, databuffer_pos, response, 80,  2);

  dumpHex(data_buffer, databuffer_pos, response, 82,  2);
  response.concat(F("\tSpenning fase 1: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 82)/10.0);
  response.concat(F("V"));
  if (hexToShort(data_buffer, databuffer_pos, 82) != 0)
  {
  volt1 = hexToShort(data_buffer, databuffer_pos, 82)/10.0;
  }
  
  dumpHex(data_buffer, databuffer_pos, response, 84,  2);
  response.concat(F("\tSpenning fase 2: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 84)/10.0);
  response.concat(F("V"));
  if (hexToShort(data_buffer, databuffer_pos, 84) != 0)
  {
  volt2 = hexToShort(data_buffer, databuffer_pos, 84)/10.0;
  }
  
  dumpHex(data_buffer, databuffer_pos, response, 86,  2);
  response.concat(F("\tSpenning fase 3: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 86)/10.0);
  response.concat(F("V"));
  if (hexToShort(data_buffer, databuffer_pos, 86) != 0)
  {
  volt3 = hexToShort(data_buffer, databuffer_pos, 86)/10.0;
  }
  
  dumpHex(data_buffer, databuffer_pos, response, 88,  6);

  dumpHex(data_buffer, databuffer_pos, response, 94,  2);
  response.concat(F("\tFrekvens: "));
  response.concat(hexToShort(data_buffer, databuffer_pos, 94)/100.0);
  response.concat(F("Hz"));
  if (hexToShort(data_buffer, databuffer_pos, 94) != 0)
  {
  frekvens = hexToShort(data_buffer, databuffer_pos, 94)/100.0;
  }
  dumpHex(data_buffer, databuffer_pos, response, 96,  1);

  dumpHex(data_buffer, databuffer_pos, response, 97,  2);
  response.concat(F("\tSjekksum er "));
  response.concat(validCrc16(data_buffer, databuffer_pos, 0, 97, 97) ? F("OK") : F("IKKE OK"));
  
  dumpHex(data_buffer, databuffer_pos, response, 99,  1);

  if (buffer_overflow)
  {
    response.concat(F("\n\n(Buffer overflowed)"));
  }

  //.send(200, F("text/plain"), response);
}

//****************************************************************


void HSSetup() {

  //************************
  //Add YOUR SETUP HERE;
  
    //in_setup_mode = false;
    
    databuffer_pos = 0;
    buffer_overflow = false;
    databuffer_receive_time = 0L;

    Serial.begin(9600, SERIAL_MODE);
    Serial.setDebugOutput(false);

//    read_persistent_params();

  //************************


}


void HSloop() {


  //************************
  //Add YOUR CODE HERE;
  //************************
  /* To Send Data to Homeseer use SendToHS(Device,Value)
    Eg.. SendToHS(1,200); where 1 is the API device in homeseer and 200 is the value to send
    To Recieve data from Homeseer look up the FromHS array that is updated when the device value changes.
    Eg.. FromHS[5] would be the data from API Output device 5
    All code that is located just below this block will execute regardless of connection status!
    You can include SendToHS() calls, however when there isn't an active connection, it will just return and continue.
    If you only want code to execute when HomeSeer is connected, put it inside the if statement below.
  */

  /*Execute regardless of connection status*/

HTTPClient http;

  if (Serial.available())
  {
    serialEvent();
    
    }
    
  if (IsConnected == true) {
    /*Execute ONLY when HomeSeer is connected*/
    handleRequest();
    if(forrigeEffekt != effekt && effekt != 0)
    {
    SendToHS(1, effekt);
    SendToHS(2, total);
    SendToHS(3, volt1);
    SendToHS(4, volt2);
    SendToHS(5, volt3);
    SendToHS(6, frekvens);
    forrigeEffekt = effekt;
   


    }
    
    
  }

}

//************Do not change anything after Here*****************

  • Thanks 1
Lenke til kommentar
Del på andre sider

Er det andre som har fått åpnet opp HAN porten på Aidon måler?

Etter oppdateringen sluttet den å sende ut proprietære meldinger, men nå har everket fått åpnet opp.

Ser at det er på tide å komme i gang med kodingen til denne. Med seriell monitor er det tydelig nå at det kommer meldinger med et par sekunders intervall. ?

Lenke til kommentar
Del på andre sider

On 19/12/2018 at 21:31, GeneralVirus said:

Noen eksperter her som har lyst til å hjelpe til å konvertere Aidon koden over til Kamstrup? Er ikke noe god på dette her.

jeg er ikke ekspert men klarte å kode opp 10 sekunders meldingen. Holder på med timesmeldingen nå..

du trenger å kopiere inn denne filen på src/han-port-1.14 katalogen og så kjøre make

Jeg bruker vnc viewer til å overføre filen :)

 

read.c

  • Thanks 1
Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.