Subversion Repositories HomeAutomation

Rev

Rev 976 | Blame | 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.             unsigned 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.         else if (iter->second.getType() == "hexstring")
  323.         {
  324.             for (int n = 0; n < iter->second.getValue().length(); n++)
  325.             {
  326.                 if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
  327.                     heighestBit = iter->second.getStartBit()+n*4 + 4;
  328.  
  329.                 string character;
  330.                 character += iter->second.getValue()[n];
  331.  
  332.                 bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
  333.             }
  334.         }
  335.     }
  336.  
  337.     bin = bin.substr(0, heighestBit);
  338.  
  339.     //cout << bin2hex(bin) << endl;
  340.  
  341.     return bin2hex(bin);
  342. }
  343.  
  344. map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
  345. {
  346.     map<string, CanVariable> variables;
  347.     XmlNode commandsNode = xmlNode.findChild("commands");
  348.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  349.  
  350.     string dataBin = hex2bin(dataHex);
  351.     //string dataString = "{";
  352.  
  353.     for (int n = 0; n < commandNodes.size(); n++)
  354.     {
  355.         map<string, string> attributes = commandNodes[n].getAttributes();
  356.  
  357.         bool correct = false;
  358.  
  359.         if (commandId >= 128)
  360.         {
  361.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  362.             {
  363.                 correct = true;
  364.             }
  365.         }
  366.         else if (stoi(attributes["id"]) == commandId)
  367.         {
  368.             correct = true;
  369.         }
  370.  
  371.         if (correct)
  372.         {
  373.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  374.  
  375.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  376.  
  377.             for (int c = 0; c < variableNodes.size(); c++)
  378.             {
  379.                 map<string, string> attributes = variableNodes[c].getAttributes();
  380.  
  381.                 int bitStart = stoi(attributes["start_bit"]);
  382.                 int bitLength = stoi(attributes["bit_length"]);
  383.  
  384.                 string bits = dataBin.substr(bitStart, bitLength);
  385.                
  386.                 CanVariable variable;
  387.                
  388.                 variable.setName(attributes["name"]);
  389.                 variable.setType(attributes["type"]);
  390.                 variable.setUnit(attributes["unit"]);
  391.                 variable.setBitLength(bitLength);
  392.  
  393.                 //dataString += " " + attributes["name"] + " : { value : ";
  394.                 //dataString += attributes["name"] + "=";
  395.                 //dataString += attributes["name"] + ":" + attributes["type"] + ":" + attributes["bit_length"] + "=\"";
  396.  
  397.                 if (attributes["type"] == "uint")
  398.                 {
  399.                     variable.setValue(itos(bin2uint(bits)));
  400.                     //dataString += itos(bin2uint(bits));
  401.                 }
  402.                 else if (attributes["type"] == "float")
  403.                 {
  404.                     variable.setValue(ftos(bin2float(bits)));
  405.                     //dataString += ftos(bin2float(bits));
  406.                 }
  407.                 else if (attributes["type"] == "ascii")
  408.                 {
  409.                     string str;
  410.                     //dataString += "'";
  411.  
  412.                     for (int k = 0; k < bits.length(); k += 8)
  413.                     {
  414.                         str += (char)bin2uint(bits.substr(k, 8));
  415.                         //dataString += (char)bin2uint(bits.substr(k, 4));
  416.                     }
  417.  
  418.                     variable.setValue(str);
  419.                     //cout << "Parsed ascii: " << str << "\n";
  420.                     //dataString += "'";
  421.                 }
  422.                 else if (attributes["type"] == "hexstring")
  423.                 {
  424.                     string str;
  425.  
  426.                     for (int k = 0; k < bits.length(); k += 4)
  427.                     {
  428.                         str += bin2hex(bits.substr(k, 4));
  429.                         //dataString += (char)bin2uint(bits.substr(k, 4));
  430.                     }
  431.  
  432.                     variable.setValue(str);
  433.                 }
  434.  
  435.                 variables[attributes["name"]] = variable;
  436.  
  437.                 //dataString += ", type : '" + attributes["type"] + "', bits : " + attributes["bit_length"] + ", unit : '" + attributes["unit"] + "' },";
  438.  
  439.                 //dataString += ",";
  440.                 //dataString += "\",";
  441.             }
  442.  
  443.             //dataString = trim(dataString, ',');
  444.  
  445.             //dataString += " }";
  446.  
  447.             //return dataString;
  448.  
  449.  
  450.             return variables;
  451.         }
  452.     }
  453.  
  454.     //return dataString + " ]";
  455.     return variables;
  456. }
  457.  
  458. map<string, CanVariable> CanIdTranslator::translateHeartbeatData(string dataHex)
  459. {
  460.     map<string, CanVariable> variables;
  461.  
  462.     string dataBin = hex2bin(dataHex);
  463.     string bits = dataBin.substr(0, 32);
  464.  
  465.     CanVariable canVariable("HardwareId", itos(bin2uint(bits)), "uint", "");
  466.     canVariable.setBitLength(32);
  467.  
  468.     variables["HardwareId"] = canVariable;
  469.  
  470.     return variables;
  471.  
  472.     //return "{ HardwareId : { value : " + itos(bin2uint(bits)) + ", type : 'uint', bits : 32, unit : '' }";
  473.     //return "HardwareId:uint:32=\"" + itos(bin2uint(bits)) + "\"";
  474. }
  475.