Subversion Repositories HomeAutomation

Rev

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