Subversion Repositories HomeAutomation

Rev

Rev 976 | Go to most recent revision | Blame | Last modification | View Log | SVN | RSS feed

  1. /***************************************************************************
  2.  *   Copyright (C) November 28, 2008 by Mattias Runge                             *
  3.  *   mattias@runge.se                                                      *
  4.  *   canmessage.cpp                                            *
  5.  *                                                                         *
  6.  *   This program is free software; you can redistribute it and/or modify  *
  7.  *   it under the terms of the GNU General Public License as published by  *
  8.  *   the Free Software Foundation; either version 2 of the License, or     *
  9.  *   (at your option) any later version.                                   *
  10.  *                                                                         *
  11.  *   This program is distributed in the hope that it will be useful,       *
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  14.  *   GNU General Public License for more details.                          *
  15.  *                                                                         *
  16.  *   You should have received a copy of the GNU General Public License     *
  17.  *   along with this program; if not, write to the                         *
  18.  *   Free Software Foundation, Inc.,                                       *
  19.  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  20.  ***************************************************************************/
  21.  
  22. #include <string>
  23. #include <iostream>
  24. #include "canidtranslator.h"
  25. #include "canmessage.h"
  26.  
  27. void CanMessage::setRaw(string rawHex)
  28. {
  29.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  30.     //SyslogStream &slog = SyslogStream::getInstance();
  31.  
  32.     //PKT 00060102 1 0 00 00 c4
  33.  
  34.     rawHex = trim(rawHex, '\n');
  35.     rawHex = trim(rawHex);
  36.  
  37.     vector<string> parts = explode(" ", rawHex);
  38.  
  39.     if (parts.size() < 2 || parts[0].compare("PKT") != 0)
  40.     {
  41.         //slog << "Malformed can message received from canDaemon: \"" << rawHex << "\"\n";
  42.         throw new CanMessageException("Malformed can message received from canDaemon");
  43.     }
  44.  
  45.     myRawHeaderBin = hex2bin(parts[1]);
  46.  
  47.     myIsHeartbeat = (parts[1] == translator.getDefineId("HeartbeatHeader", "None"));
  48.  
  49.     // This is not a module id header, but heartbeats are sent this way so we want to check it anyway
  50.     if (myIsHeartbeat)
  51.     {
  52.         string rawHexData = "";
  53.         for (int n = 4; n < parts.size(); n++)
  54.         {
  55.             rawHexData += parts[n];
  56.         }
  57.  
  58.         myData = translator.translateHeartbeatData(rawHexData);
  59.     }
  60.     else
  61.     {
  62.         myClassName = translator.lookupClassName(bin2uint(myRawHeaderBin.substr(3, 4)));
  63.  
  64.         if (myClassName == "")
  65.         {
  66.             myIsUnknown = true;
  67.             return;
  68.         }
  69.  
  70.         myDirectionFlag = translator.lookupDirectionFlag(bin2uint(myRawHeaderBin.substr(7, 1)));
  71.         myModuleName = translator.lookupModuleName(bin2uint(myRawHeaderBin.substr(8, 8)));
  72.  
  73.         myModuleId = bin2uint(myRawHeaderBin.substr(16, 8));
  74.  
  75.         int commandId = bin2uint(myRawHeaderBin.substr(24, 8));
  76.         myCommandName = translator.lookupCommandName(commandId, myModuleName);
  77.  
  78.         string rawHexData = "";
  79.         for (int n = 4; n < parts.size(); n++)
  80.         {
  81.             rawHexData += parts[n];
  82.         }
  83.        
  84.         myData = translator.translateData(commandId, myModuleName, rawHexData);
  85.     }
  86. }
  87.  
  88. string CanMessage::getRaw()
  89. {
  90.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  91.  
  92.     string rawHex = "PKT ";
  93.  
  94.     string bin = "000";
  95.  
  96.     int classId = translator.resolveClassId(myClassName);
  97.     if (classId == -1)
  98.         bin += "0000";
  99.     else
  100.         bin += uint2bin(classId, 4);
  101.  
  102.  
  103.     bin += uint2bin(translator.resolveDirectionFlag(myDirectionFlag), 1);
  104.  
  105.  
  106.     int moduleTypeId = translator.resolveModuleId(myModuleName);
  107.     if (moduleTypeId == -1)
  108.         bin += "00000000";
  109.     else
  110.         bin += uint2bin(moduleTypeId, 8);
  111.  
  112.  
  113.     int moduleId = myModuleId;
  114.     bin += uint2bin(moduleId, 8);
  115.  
  116.  
  117.     int commandNameId = translator.resolveCommandId(myCommandName, myModuleName);
  118.     if (commandNameId == -1)
  119.         bin += "00000000";
  120.     else
  121.         bin += uint2bin(commandNameId, 8);
  122.  
  123.  
  124.    
  125.     rawHex += bin2hex(bin);
  126.    
  127.     rawHex += " 1 0";
  128.  
  129.     string dataHex = translator.translateDataToHex(commandNameId, myModuleName, myData);
  130.  
  131.     while (dataHex.size() > 0)
  132.     {
  133.         string hex = dataHex.substr(0, 2);
  134.         dataHex.erase(0, 2);
  135.         rawHex += " " + hex;
  136.     }
  137.  
  138.     rawHex += "\n";
  139.  
  140.     return rawHex;
  141. }
  142.  
  143. void CanMessage::setJSON(string json)
  144. {
  145.     cout << json << "\n";
  146.     string data = trim(json, '(');
  147.     data = trim(data, ')');
  148.     data = trim(data, '{');
  149.     data = trim(data, '{');
  150.     data = trim(data, ' ');
  151.  
  152.     vector<string> parts = explode(",", data);
  153.  
  154.     for (int n = 0; n < parts.size(); n++)
  155.     {
  156.         string part = trim(parts[n], ' ');
  157.         vector<string> innerParts = explode(":", part);
  158.  
  159.         int c = 0;
  160.         if (innerParts[0] == "data")
  161.             c++;
  162.  
  163.         string name = trim(innerParts[c], ' ');
  164.         name = trim(name, '{');
  165.         name = trim(name, '}');
  166.         string value = trim(innerParts[c+1], ' ');
  167.         value = trim(value, '{');
  168.         value = trim(value, '}');
  169.         value = trim(value, '"');
  170.        
  171.         cout << "\n" << name << "=" << value << "\n";
  172.  
  173.         if (name == "className")
  174.             myClassName = value;
  175.         else if (name == "directionFlag")
  176.             myDirectionFlag = value;
  177.         else if (name == "moduleName")
  178.             myModuleName = value;
  179.         else if (name == "moduleId")
  180.             myModuleId = stoi(value);
  181.         else if (name == "commandName")
  182.             myCommandName = value;
  183.         else
  184.         {
  185.             CanVariable canVariable(name, value, "", "");
  186.             myData[name] = canVariable;
  187.         }
  188.     }
  189. }
  190.  
  191. string CanMessage::getJSON()
  192. {
  193.     string json = "{ ";
  194.  
  195.     json += "className : '" + myClassName + "', ";
  196.     json += "directionFlag : '" + myDirectionFlag + "', ";
  197.     json += "moduleName : '" + myModuleName + "', ";
  198.     json += "moduleId : " + itos(myModuleId) + ", ";
  199.     json += "commandName : '" + myCommandName + "', ";
  200.  
  201.     json += "data : {";
  202.  
  203.     map<string, CanVariable>::iterator iter;
  204.  
  205.     for (iter = myData.begin(); iter != myData.end(); iter++)
  206.     {
  207.         json += " " + iter->first + " : { ";
  208.  
  209.         json += "unit : '" + iter->second.getUnit() + "', ";
  210.         json += "type : '" + iter->second.getType() + "', ";
  211.         json += "value : ";
  212.  
  213.         if (iter->second.getType() == "uint")
  214.         {
  215.             json += iter->second.getValue();
  216.         }
  217.         else if (iter->second.getType() == "float")
  218.         {
  219.             json += iter->second.getValue();
  220.         }
  221.         else if (iter->second.getType() == "ascii" || iter->second.getType() == "hexstring")
  222.         {
  223.             json += "'" + iter->second.getValue() + "'";
  224.         }
  225.  
  226.         json += " },";
  227.     }
  228.  
  229.     json = trim(json, ',');
  230.  
  231.     json += " }";
  232.  
  233.     return json + " }";
  234. }
  235.  
  236. string CanMessage::getJSONData()
  237. {
  238.     string json = "{";
  239.  
  240.     map<string, CanVariable>::iterator iter;
  241.  
  242.     for (iter = myData.begin(); iter != myData.end(); iter++)
  243.     {
  244.         json += " " + iter->first + " : ";
  245.  
  246.         if (iter->second.getType() == "uint")
  247.         {
  248.             json += iter->second.getValue();
  249.         }
  250.         else if (iter->second.getType() == "float")
  251.         {
  252.             json += iter->second.getValue();
  253.         }
  254.         else if (iter->second.getType() == "ascii" || iter->second.getType() == "hexstring")
  255.         {
  256.             json += "'" + escape(iter->second.getValue()) + "'";
  257.         }
  258.  
  259.         json += ",";
  260.     }
  261.  
  262.     json = trim(json, ',');
  263.  
  264.     return json + " }";
  265. }
  266.