Subversion Repositories HomeAutomation

Rev

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

  1. /***************************************************************************
  2.  *   Copyright (C) November 28, 2008 by Mattias Runge                             *
  3.  *   mattias@runge.se                                                      *
  4.  *   canidtranslator.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 "canidtranslator.h"
  23.  
  24. CanIdTranslator* CanIdTranslator::myInstance = NULL;
  25.  
  26. CanIdTranslator& CanIdTranslator::getInstance()
  27. {
  28.     if (myInstance == NULL)
  29.     {
  30.         myInstance = new CanIdTranslator();
  31.     }
  32.  
  33.     return *myInstance;
  34. }
  35.  
  36. void CanIdTranslator::deleteInstance()
  37. {
  38.     delete myInstance;
  39.     myInstance = NULL;
  40. }
  41.  
  42. CanIdTranslator::CanIdTranslator()
  43. {
  44.     SyslogStream &slog = SyslogStream::getInstance();
  45.  
  46.     string filename = Settings::get("CanIdXMLFile");
  47.  
  48.     xmlNode.load(filename.c_str());
  49.  
  50.     slog << "Loading definitions from " << filename << ".\n";
  51. }
  52.  
  53. string CanIdTranslator::lookupClassName(int classId)
  54. {
  55.     XmlNode classesNode = xmlNode.findChild("classes");
  56.     vector<XmlNode> classNodes = classesNode.getChildren();
  57.  
  58.     for (int n = 0; n < classNodes.size(); n++)
  59.     {
  60.         map<string, string> attributes = classNodes[n].getAttributes();
  61.  
  62.         if (stoi(attributes["id"]) == classId)
  63.         {
  64.             return attributes["name"];
  65.         }
  66.     }
  67.  
  68.     return "";
  69. }
  70.  
  71. int CanIdTranslator::resolveClassId(string className)
  72. {
  73.     XmlNode classesNode = xmlNode.findChild("classes");
  74.     vector<XmlNode> classNodes = classesNode.getChildren();
  75.  
  76.     for (int n = 0; n < classNodes.size(); n++)
  77.     {
  78.         map<string, string> attributes = classNodes[n].getAttributes();
  79.  
  80.         if (attributes["name"].compare(className) == 0)
  81.         {
  82.             return stoi(attributes["id"]);
  83.         }
  84.     }
  85.  
  86.     return -1;
  87. }
  88.  
  89. string CanIdTranslator::lookupCommandName(int commandId, string moduleName)
  90. {
  91.     XmlNode commandsNode = xmlNode.findChild("commands");
  92.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  93.  
  94.     for (int n = 0; n < commandNodes.size(); n++)
  95.     {
  96.         map<string, string> attributes = commandNodes[n].getAttributes();
  97.  
  98.         if (commandId > 128)
  99.         {
  100.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  101.             {
  102.                 return attributes["name"];
  103.             }
  104.         }
  105.         else if (stoi(attributes["id"]) == commandId)
  106.         {
  107.             return attributes["name"];
  108.         }
  109.     }
  110.  
  111.     return "";
  112. }
  113.  
  114. int CanIdTranslator::resolveCommandId(string commandName, string moduleName)
  115. {
  116.     XmlNode commandsNode = xmlNode.findChild("commands");
  117.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  118.  
  119.     for (int n = 0; n < commandNodes.size(); n++)
  120.     {
  121.         map<string, string> attributes = commandNodes[n].getAttributes();
  122.  
  123.         if (attributes["name"].compare(commandName) == 0)
  124.         {
  125.             int commandId = stoi(attributes["id"]);
  126.  
  127.             if (commandId > 128)
  128.             {
  129.                 if (attributes["module"] == moduleName)
  130.                 {
  131.                     return commandId;
  132.                 }
  133.             }
  134.             else
  135.             {
  136.                 return commandId;
  137.             }
  138.         }
  139.     }
  140.  
  141.     return -1;
  142. }
  143.  
  144. string CanIdTranslator::getDefineId(string name, string group)
  145. {
  146.     XmlNode definesNode = xmlNode.findChild("defines");
  147.     vector<XmlNode> defineNodes = definesNode.getChildren();
  148.  
  149.     for (int n = 0; n < defineNodes.size(); n++)
  150.     {
  151.         map<string, string> attributes = defineNodes[n].getAttributes();
  152.  
  153.         if (attributes["group"] == group && attributes["name"] == name)
  154.         {
  155.             return attributes["id"];
  156.         }
  157.     }
  158.  
  159.     return "";
  160. }
  161.  
  162. string CanIdTranslator::lookupDirectionFlag(int directionFlag)
  163. {
  164.     XmlNode definesNode = xmlNode.findChild("defines");
  165.     vector<XmlNode> defineNodes = definesNode.getChildren();
  166.  
  167.     for (int n = 0; n < defineNodes.size(); n++)
  168.     {
  169.         map<string, string> attributes = defineNodes[n].getAttributes();
  170.  
  171.         if (attributes["group"].compare("DirectionFlag") == 0 && stoi(attributes["id"]) == directionFlag)
  172.         {
  173.             return attributes["name"];
  174.         }
  175.     }
  176.  
  177.     return "";
  178. }
  179.  
  180. int CanIdTranslator::resolveDirectionFlag(string directionName)
  181. {
  182.     XmlNode definesNode = xmlNode.findChild("defines");
  183.     vector<XmlNode> defineNodes = definesNode.getChildren();
  184.  
  185.     for (int n = 0; n < defineNodes.size(); n++)
  186.     {
  187.         map<string, string> attributes = defineNodes[n].getAttributes();
  188.  
  189.         if (attributes["group"].compare("DirectionFlag") == 0 && attributes["name"].compare(directionName) == 0)
  190.         {
  191.             return stoi(attributes["id"]);
  192.         }
  193.     }
  194.  
  195.     return -1;
  196. }
  197.  
  198. string CanIdTranslator::lookupModuleName(int moduleId)
  199. {
  200.     XmlNode modulesNode = xmlNode.findChild("modules");
  201.     vector<XmlNode> moduleNodes = modulesNode.getChildren();
  202.  
  203.     for (int n = 0; n < moduleNodes.size(); n++)
  204.     {
  205.         map<string, string> attributes = moduleNodes[n].getAttributes();
  206.  
  207.         if (stoi(attributes["id"]) == moduleId)
  208.         {
  209.             return attributes["name"];
  210.         }
  211.     }
  212.  
  213.     return "";
  214. }
  215.  
  216. int CanIdTranslator::resolveModuleId(string moduleName)
  217. {
  218.     XmlNode modulesNode = xmlNode.findChild("modules");
  219.     vector<XmlNode> moduleNodes = modulesNode.getChildren();
  220.  
  221.     for (int n = 0; n < moduleNodes.size(); n++)
  222.     {
  223.         map<string, string> attributes = moduleNodes[n].getAttributes();
  224.  
  225.         if (attributes["name"].compare(moduleName) == 0)
  226.         {
  227.             return stoi(attributes["id"]);
  228.         }
  229.     }
  230.  
  231.     return -1;
  232. }
  233.  
  234. string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> data)
  235. {
  236.     XmlNode commandsNode = xmlNode.findChild("commands");
  237.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  238.  
  239.     map<string, CanVariable> sortedData;
  240.  
  241.     for (int n = 0; n < commandNodes.size(); n++)
  242.     {
  243.         map<string, string> attributes = commandNodes[n].getAttributes();
  244.  
  245.         bool correct = false;
  246.  
  247.         if (commandId > 128)
  248.         {
  249.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  250.             {
  251.                 correct = true;
  252.             }
  253.         }
  254.         else if (stoi(attributes["id"]) == commandId)
  255.         {
  256.             correct = true;
  257.         }
  258.  
  259.         if (correct)
  260.         {
  261.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  262.  
  263.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  264.  
  265.             for (int c = 0; c < variableNodes.size(); c++)
  266.             {
  267.                 map<string, string> attributes = variableNodes[c].getAttributes();
  268.  
  269.                 if (data.find(attributes["name"]) != data.end())
  270.                 {
  271.                     int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
  272.                     int bitLength = stoi(attributes["bit_length"]);
  273.  
  274.                     sortedData[attributes["name"]].setType(attributes["type"]);
  275.                     sortedData[attributes["name"]].setUnit(attributes["unit"]);
  276.                     sortedData[attributes["name"]].setBitLength(bitLength);
  277.                     sortedData[attributes["name"]].setBitLength(bitLength);
  278.                     sortedData[attributes["name"]].setStartBit(bitStart);
  279.                     sortedData[attributes["name"]].setName(attributes["name"]);
  280.                     sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
  281.                 }
  282.             }
  283.         }
  284.     }
  285.  
  286.     string bin = "0000000000000000000000000000000000000000000000000000000000000000";
  287.     int heighestBit = 0;
  288.  
  289.     map<string, CanVariable>::iterator iter;
  290.  
  291.     for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
  292.     {
  293.         if (iter->second.getType() == "uint")
  294.         {
  295.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  296.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  297.  
  298.             //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
  299.             int a = stoi(iter->second.getValue());
  300.            
  301.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
  302.         }
  303.         else if (iter->second.getType() == "float")
  304.         {
  305.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  306.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  307.  
  308.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
  309.         }
  310.         else if (iter->second.getType() == "ascii")
  311.         {
  312.             //cout << iter->second.getValue() << endl;
  313.             for (int n = 0; n < iter->second.getValue().length(); n++)
  314.             {
  315.                 if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
  316.                     heighestBit = iter->second.getStartBit()+n*8 + 8;
  317.  
  318.                 //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
  319.                 bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
  320.             }
  321.         }
  322.     }
  323.  
  324.     bin = bin.substr(0, heighestBit);
  325.  
  326.     //cout << bin2hex(bin) << endl;
  327.  
  328.     return bin2hex(bin);
  329. }
  330.  
  331. map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
  332. {
  333.     map<string, CanVariable> variables;
  334.     XmlNode commandsNode = xmlNode.findChild("commands");
  335.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  336.  
  337.     string dataBin = hex2bin(dataHex);
  338.     //string dataString = "{";
  339.  
  340.     for (int n = 0; n < commandNodes.size(); n++)
  341.     {
  342.         map<string, string> attributes = commandNodes[n].getAttributes();
  343.  
  344.         bool correct = false;
  345.  
  346.         if (commandId > 128)
  347.         {
  348.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  349.             {
  350.                 correct = true;
  351.             }
  352.         }
  353.         else if (stoi(attributes["id"]) == commandId)
  354.         {
  355.             correct = true;
  356.         }
  357.  
  358.         if (correct)
  359.         {
  360.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  361.  
  362.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  363.  
  364.             for (int c = 0; c < variableNodes.size(); c++)
  365.             {
  366.                 map<string, string> attributes = variableNodes[c].getAttributes();
  367.  
  368.                 int bitStart = stoi(attributes["start_bit"]);
  369.                 int bitLength = stoi(attributes["bit_length"]);
  370.  
  371.                 string bits = dataBin.substr(bitStart, bitLength);
  372.                
  373.                 CanVariable variable;
  374.                
  375.                 variable.setName(attributes["name"]);
  376.                 variable.setType(attributes["type"]);
  377.                 variable.setUnit(attributes["unit"]);
  378.                 variable.setBitLength(bitLength);
  379.  
  380.                 //dataString += " " + attributes["name"] + " : { value : ";
  381.                 //dataString += attributes["name"] + "=";
  382.                 //dataString += attributes["name"] + ":" + attributes["type"] + ":" + attributes["bit_length"] + "=\"";
  383.  
  384.                 if (attributes["type"] == "uint")
  385.                 {
  386.                     variable.setValue(itos(bin2uint(bits)));
  387.                     //dataString += itos(bin2uint(bits));
  388.                 }
  389.                 else if (attributes["type"] == "float")
  390.                 {
  391.                     variable.setValue(ftos(bin2float(bits)));
  392.                     //dataString += ftos(bin2float(bits));
  393.                 }
  394.                 else if (attributes["type"] == "ascii")
  395.                 {
  396.                     string str;
  397.                     //dataString += "'";
  398.  
  399.                     for (int k = 0; k < bits.length(); k += 8)
  400.                     {
  401.                         str += (char)bin2uint(bits.substr(k, 8));
  402.                         //dataString += (char)bin2uint(bits.substr(k, 4));
  403.                     }
  404.  
  405.                     variable.setValue(str);
  406.                     //cout << "Parsed ascii: " << str << "\n";
  407.                     //dataString += "'";
  408.                 }
  409.  
  410.                 variables[attributes["name"]] = variable;
  411.  
  412.                 //dataString += ", type : '" + attributes["type"] + "', bits : " + attributes["bit_length"] + ", unit : '" + attributes["unit"] + "' },";
  413.  
  414.                 //dataString += ",";
  415.                 //dataString += "\",";
  416.             }
  417.  
  418.             //dataString = trim(dataString, ',');
  419.  
  420.             //dataString += " }";
  421.  
  422.             //return dataString;
  423.  
  424.  
  425.             return variables;
  426.         }
  427.     }
  428.  
  429.     //return dataString + " ]";
  430.     return variables;
  431. }
  432.  
  433. map<string, CanVariable> CanIdTranslator::translateHeartbeatData(string dataHex)
  434. {
  435.     map<string, CanVariable> variables;
  436.  
  437.     string dataBin = hex2bin(dataHex);
  438.     string bits = dataBin.substr(0, 32);
  439.  
  440.     CanVariable canVariable("HardwareId", itos(bin2uint(bits)), "uint", "");
  441.     canVariable.setBitLength(32);
  442.  
  443.     variables["HardwareId"] = canVariable;
  444.  
  445.     return variables;
  446.  
  447.     //return "{ HardwareId : { value : " + itos(bin2uint(bits)) + ", type : 'uint', bits : 32, unit : '' }";
  448.     //return "HardwareId:uint:32=\"" + itos(bin2uint(bits)) + "\"";
  449. }
  450.