Browse Source

fixed problem with calculated parameters

Krystian Lewandowski 9 years ago
parent
commit
384b86373d

+ 1 - 0
.idea/.name

@@ -0,0 +1 @@
+PiMonitor

+ 9 - 0
.idea/PiMonitor.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 2.7.8 (/opt/local/bin/python2.7)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+

+ 5 - 0
.idea/encodings.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+

+ 5 - 0
.idea/misc.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7.5 (/usr/bin/python)" project-jdk-type="Python SDK" />
+</project>
+

+ 9 - 0
.idea/modules.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/PiMonitor.iml" filepath="$PROJECT_DIR$/.idea/PiMonitor.iml" />
+    </modules>
+  </component>
+</project>
+

+ 5 - 0
.idea/scopes/scope_settings.xml

@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>

+ 7 - 0
.idea/vcs.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
+

+ 603 - 0
.idea/workspace.xml

@@ -0,0 +1,603 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="1591b6fa-ad4f-4d7a-b643-0b1859455660" name="Default" comment="">
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/PiMonitor.iml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/encodings.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/misc.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/modules.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/scopes/scope_settings.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/.idea/vcs.xml" />
+      <change type="DELETED" beforePath="$PROJECT_DIR$/.project" afterPath="" />
+      <change type="DELETED" beforePath="$PROJECT_DIR$/.pydevproject" afterPath="" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PM.py" afterPath="$PROJECT_DIR$/pimonitor/PM.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMConnection.py" afterPath="$PROJECT_DIR$/pimonitor/PMConnection.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMDemoConnection.py" afterPath="$PROJECT_DIR$/pimonitor/PMDemoConnection.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMMain.py" afterPath="$PROJECT_DIR$/pimonitor/PMMain.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMPacket.py" afterPath="$PROJECT_DIR$/pimonitor/PMPacket.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMParameter.py" afterPath="$PROJECT_DIR$/pimonitor/PMParameter.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/ui/PMScreen.py" afterPath="$PROJECT_DIR$/pimonitor/ui/PMScreen.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/ui/PMSingleWindow.py" afterPath="$PROJECT_DIR$/pimonitor/ui/PMSingleWindow.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMUtils.py" afterPath="$PROJECT_DIR$/pimonitor/PMUtils.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/ui/PMWindow.py" afterPath="$PROJECT_DIR$/pimonitor/ui/PMWindow.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pimonitor/PMXmlParser.py" afterPath="$PROJECT_DIR$/pimonitor/PMXmlParser.py" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/run.sh" afterPath="$PROJECT_DIR$/run.sh" />
+    </list>
+    <ignored path="PiMonitor.iws" />
+    <ignored path=".idea/workspace.xml" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+  <component name="CreatePatchCommitExecutor">
+    <option name="PATCH_PATH" value="" />
+  </component>
+  <component name="DaemonCodeAnalyzer">
+    <disable_hints />
+  </component>
+  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+  <component name="FavoritesManager">
+    <favorites_list name="PiMonitor" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf>
+      <file leaf-file-name="PMMain.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMMain.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="1073" max-vertical-offset="2115">
+              <caret line="88" column="45" selection-start-line="88" selection-start-column="45" selection-end-line="88" selection-end-column="45" />
+              <folding>
+                <element signature="e#72#81#0" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMParameter.py" pinned="false" current="true" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMParameter.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="1.7022809" vertical-offset="682" max-vertical-offset="2925">
+              <caret line="140" column="21" selection-start-line="140" selection-start-column="21" selection-end-line="140" selection-end-column="21" />
+              <folding>
+                <element signature="e#47#56#0" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMXmlParser.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMXmlParser.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="728" max-vertical-offset="3105">
+              <caret line="66" column="0" selection-start-line="66" selection-start-column="0" selection-end-line="66" selection-end-column="0" />
+              <folding>
+                <element signature="e#47#61#0" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMScreen.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMScreen.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="2333" max-vertical-offset="3705">
+              <caret line="172" column="36" selection-start-line="172" selection-start-column="36" selection-end-line="172" selection-end-column="36" />
+              <folding>
+                <element signature="e#47#56#0" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMSingleWindow.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMSingleWindow.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="240" max-vertical-offset="1095">
+              <caret line="26" column="0" selection-start-line="26" selection-start-column="0" selection-end-line="26" selection-end-column="0" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMPacket.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMPacket.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1905">
+              <caret line="12" column="4" selection-start-line="12" selection-start-column="4" selection-end-line="12" selection-end-column="4" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMWindow.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMWindow.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="173" max-vertical-offset="1320">
+              <caret line="28" column="47" selection-start-line="28" selection-start-column="47" selection-end-line="28" selection-end-column="47" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMDemoConnection.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMDemoConnection.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1290">
+              <caret line="19" column="8" selection-start-line="19" selection-start-column="8" selection-end-line="19" selection-end-column="8" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PMConnection.py" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/pimonitor/PMConnection.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2100">
+              <caret line="19" column="8" selection-start-line="19" selection-start-column="8" selection-end-line="19" selection-end-column="8" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FindManager">
+    <FindUsagesManager>
+      <setting name="OPEN_NEW_TAB" value="true" />
+    </FindUsagesManager>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="changedFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pimonitor/PM.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMUtils.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMXmlParser.py" />
+        <option value="$PROJECT_DIR$/pimonitor/ui/PMWindow.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMMain.py" />
+        <option value="$PROJECT_DIR$/pimonitor/ui/PMScreen.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMPacket.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMConnection.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMDemoConnection.py" />
+        <option value="$PROJECT_DIR$/pimonitor/ui/PMSingleWindow.py" />
+        <option value="$PROJECT_DIR$/pimonitor/PMParameter.py" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectFrameBounds">
+    <option name="y" value="22" />
+    <option name="width" value="2560" />
+    <option name="height" value="1353" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectReloadState">
+    <option name="STATE" value="0" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+    </navigator>
+    <panes>
+      <pane id="Scope" />
+      <pane id="ProjectPane">
+        <subPane>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="pimonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="pimonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="ui" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="PiMonitor" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="data" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+        </subPane>
+      </pane>
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="options.lastSelected" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
+    <property name="options.splitter.main.proportions" value="0.3" />
+    <property name="options.splitter.details.proportions" value="0.2" />
+    <property name="options.searchVisible" value="true" />
+    <property name="recentsLimit" value="5" />
+    <property name="restartRequiresConfirmation" value="true" />
+  </component>
+  <component name="PyConsoleOptionsProvider">
+    <option name="myPythonConsoleState">
+      <console-settings />
+    </option>
+  </component>
+  <component name="RunManager" selected="Python.PMMain">
+    <configuration default="false" name="PMMain" type="PythonConfigurationType" factoryName="Python" temporary="true">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="IS_MODULE_SDK" value="true" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="$PROJECT_DIR$/pimonitor/PMMain.py" />
+      <option name="PARAMETERS" value="" />
+      <RunnerSettings RunnerId="PythonRunner" />
+      <ConfigurationWrapper RunnerId="PythonRunner" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="py.test">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="testToRun" value="" />
+      <option name="keywords" value="" />
+      <option name="params" value="" />
+      <option name="USE_PARAM" value="false" />
+      <option name="USE_KEYWORD" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Nosetests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="PARAMS" value="" />
+      <option name="USE_PARAM" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="PythonConfigurationType" factoryName="Python">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="PARAMETERS" value="" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Unittests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <option name="PUREUNITTEST" value="true" />
+      <option name="PARAMS" value="" />
+      <option name="USE_PARAM" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Doctests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <method />
+    </configuration>
+    <configuration default="true" type="tests" factoryName="Attests">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs />
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="PiMonitor" />
+      <option name="SCRIPT_NAME" value="" />
+      <option name="CLASS_NAME" value="" />
+      <option name="METHOD_NAME" value="" />
+      <option name="FOLDER_NAME" value="" />
+      <option name="TEST_TYPE" value="TEST_SCRIPT" />
+      <option name="PATTERN" value="" />
+      <option name="USE_PATTERN" value="false" />
+      <method />
+    </configuration>
+    <list size="1">
+      <item index="0" class="java.lang.String" itemvalue="Python.PMMain" />
+    </list>
+    <recent_temporary>
+      <list size="1">
+        <item index="0" class="java.lang.String" itemvalue="Python.PMMain" />
+      </list>
+    </recent_temporary>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false" />
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="1591b6fa-ad4f-4d7a-b643-0b1859455660" name="Default" comment="" />
+      <created>1406746534774</created>
+      <updated>1406746534774</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="0" y="22" width="2560" height="1353" extended-state="0" />
+    <editor active="true" />
+    <layout>
+      <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.13671875" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3995327" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32943925" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+    </layout>
+  </component>
+  <component name="Vcs.Log.UiProperties">
+    <option name="RECENTLY_FILTERED_USER_GROUPS">
+      <collection />
+    </option>
+    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
+      <collection />
+    </option>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="VcsManagerConfiguration">
+    <option name="myTodoPanelSettings">
+      <TodoPanelSettings />
+    </option>
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/pimonitor/__init__.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1256">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PM.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="525">
+          <caret line="4" column="0" selection-start-line="4" selection-start-column="0" selection-end-line="4" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMUtils.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1185">
+          <caret line="11" column="4" selection-start-line="11" selection-start-column="4" selection-end-line="11" selection-end-column="4" />
+          <folding>
+            <element signature="e#47#56#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMXmlParser.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="728" max-vertical-offset="3105">
+          <caret line="66" column="0" selection-start-line="66" selection-start-column="0" selection-end-line="66" selection-end-column="0" />
+          <folding>
+            <element signature="e#47#61#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMWindow.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="173" max-vertical-offset="1320">
+          <caret line="28" column="47" selection-start-line="28" selection-start-column="47" selection-end-line="28" selection-end-column="47" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMMain.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="1073" max-vertical-offset="2115">
+          <caret line="88" column="45" selection-start-line="88" selection-start-column="45" selection-end-line="88" selection-end-column="45" />
+          <folding>
+            <element signature="e#72#81#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMScreen.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="2333" max-vertical-offset="3705">
+          <caret line="172" column="36" selection-start-line="172" selection-start-column="36" selection-end-line="172" selection-end-column="36" />
+          <folding>
+            <element signature="e#47#56#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMPacket.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1905">
+          <caret line="12" column="4" selection-start-line="12" selection-start-column="4" selection-end-line="12" selection-end-column="4" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMConnection.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2100">
+          <caret line="19" column="8" selection-start-line="19" selection-start-column="8" selection-end-line="19" selection-end-column="8" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMDemoConnection.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1290">
+          <caret line="19" column="8" selection-start-line="19" selection-start-column="8" selection-end-line="19" selection-end-column="8" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/ui/__init__.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1256">
+          <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/ui/PMSingleWindow.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="0.0" vertical-offset="240" max-vertical-offset="1095">
+          <caret line="26" column="0" selection-start-line="26" selection-start-column="0" selection-end-line="26" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/pimonitor/PMParameter.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state vertical-scroll-proportion="1.7022809" vertical-offset="682" max-vertical-offset="2925">
+          <caret line="140" column="21" selection-start-line="140" selection-start-column="21" selection-end-line="140" selection-end-column="21" />
+          <folding>
+            <element signature="e#47#56#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+  </component>
+</project>
+

+ 0 - 17
.project

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>PiMonitor</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.python.pydev.PyDevBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.python.pydev.pythonNature</nature>
-	</natures>
-</projectDescription>

+ 0 - 8
.pydevproject

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?eclipse-pydev version="1.0"?><pydev_project>
-<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
-<path>/PiMonitor</path>
-</pydev_pathproperty>
-<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
-<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7</pydev_property>
-</pydev_project>

+ 24 - 25
pimonitor/PM.py

@@ -1,31 +1,30 @@
-'''
+"""
 Created on 22-04-2013
 
 @author: citan
-'''
+"""
 
-import platform
 
 class PM(object):
-	
-	_instance = None
-	def __new__(cls, *args, **kwargs):
-		if not cls._instance:
-			cls._instance = super(PM, cls).__new__(cls, *args, **kwargs)
-		return cls._instance
-		
-	def __init__(self):
-		pass
-		
-	def set(self, log):
-		self._log = log
-	
-	@classmethod
-	def log(cls, message, mid=0):
-		return PM().log_impl(message, mid)
-	
-	def log_impl(self, message, mid):
-		return self._log(message, mid)
-
-	def in_demo(self):
-		return False
+    _instance = None
+
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(PM, cls).__new__(cls, *args)
+        return cls._instance
+
+    def __init__(self):
+        pass
+
+    def set(self, log):
+        self._log = log
+
+    @classmethod
+    def log(cls, message, mid=0):
+        return PM().log_impl(message, mid)
+
+    def log_impl(self, message, mid):
+        return self._log(message, mid)
+
+    def in_demo(self):
+        return False

+ 31 - 33
pimonitor/PMConnection.py

@@ -1,40 +1,41 @@
-'''
+"""
 Created on 29-03-2013
 
 @author: citan
-'''
+"""
 import serial
 import time
 
 from pimonitor.PMPacket import PMPacket
 
+
 class PMConnection(object):
-    '''
+    """
     classdocs
-    '''
+    """
 
     def __init__(self):
-        '''
+        """
         Constructor
-        '''
+        """
         self._ser = None
-    
+
     def open(self):
         self._ser = serial.Serial(
-                            port='/dev/ttyUSB0',
-                            # port='/dev/tty.usbserial-000013FA',
-                            baudrate=4800,
-                            timeout=2000,
-                            writeTimeout=55,
-                            parity=serial.PARITY_NONE,
-                            stopbits=serial.STOPBITS_ONE,
-                            bytesize=serial.EIGHTBITS)
+            port='/dev/ttyUSB0',
+            # port='/dev/tty.usbserial-000013FA',
+            baudrate=4800,
+            timeout=2000,
+            writeTimeout=55,
+            parity=serial.PARITY_NONE,
+            stopbits=serial.STOPBITS_ONE,
+            bytesize=serial.EIGHTBITS)
         time.sleep(0.2)
 
     def close(self):
-        if self._ser != None:
+        if self._ser is not None:
             self._ser.close()
-        
+
     def init(self, target):
         request_packet = PMPacket(self.get_destination(target), 0xF0, [0xBF])
         return self.send_packet(request_packet)
@@ -42,13 +43,11 @@ class PMConnection(object):
     def send_packet(self, packet):
         self._ser.write(packet.to_string())
         time.sleep(0.05)
-        
+
         out_packet = None
-        tmp = []
         data = []
 
         while self._ser.inWaiting() > 0:
-            tmp = []
 
             # read header
             tmp = self._ser.read(3)
@@ -58,7 +57,7 @@ class PMConnection(object):
             sizebytes = self._ser.read()
             data.append(sizebytes[0])
             size = ord(sizebytes[0])
-            
+
             # read data
             tmp = self._ser.read(size)
             data.extend(tmp)
@@ -70,7 +69,7 @@ class PMConnection(object):
             out_packet = PMPacket.from_array(data)
             data = []
 
-            if(packet.is_equal(out_packet)):
+            if packet.is_equal(out_packet):
                 continue
 
         return out_packet
@@ -79,23 +78,21 @@ class PMConnection(object):
         address = parameter.get_address()
         address_len = parameter.get_address_length()
 
-        data = []
+        data = [0xA8, 0x00]
 
-        data.append(0xA8)
-        data.append(0x00)
         for i in range(0, address_len):
             target_address = address + i
             data.append((target_address & 0xffffff) >> 16)
             data.append((target_address & 0xffff) >> 8)
             data.append(target_address & 0xff)
-    
+
         request_packet = PMPacket(self.get_destination(parameter.get_target()), 0xf0, data)
         return self.send_packet(request_packet)
 
     def read_parameters(self, parameters):
         data = []
         target = parameters[0].get_target()
-        
+
         data.append(0xA8)
         data.append(0x00)
         for parameter in parameters:
@@ -110,25 +107,26 @@ class PMConnection(object):
                 data.append((target_address & 0xffffff) >> 16)
                 data.append((target_address & 0xffff) >> 8)
                 data.append(target_address & 0xff)
-                
+
         request_packet = PMPacket(self.get_destination(target), 0xf0, data)
         out_packet = self.send_packet(request_packet)
-        
+
         out_data = out_packet.get_data()
         out_packets = []
         data_offset = 1  # skip E8
-        
+
         for parameter in parameters:
             address_len = parameter.get_address_length()
             single_out_data = [0xE8]
             single_out_data.extend(out_data[data_offset:address_len + data_offset])
-            single_out_packet = PMPacket(out_packet.get_destination(), out_packet.get_source(), single_out_data);
+            single_out_packet = PMPacket(out_packet.get_destination(), out_packet.get_source(), single_out_data)
             out_packets.append(single_out_packet)
             data_offset += address_len
 
         return out_packets
-     
-    def get_destination(self, target):
+
+    @staticmethod
+    def get_destination(target):
         dst = target
         if target == 1:
             dst = 0x10

+ 7 - 6
pimonitor/PMDemoConnection.py

@@ -1,8 +1,8 @@
-'''
+"""
 Created on 29-03-2013
 
 @author: citan
-'''
+"""
 from pimonitor.PM import PM
 from pimonitor.PMPacket import PMPacket
 import random
@@ -10,14 +10,14 @@ import time
 
 
 class PMDemoConnection(object):
-    '''
+    """
     classdocs
-    '''
+    """
 
     def __init__(self):
-        '''
+        """
         Constructor
-        '''
+        """
         self._ser = None
         self._log_id = None
         random.seed()
@@ -36,6 +36,7 @@ class PMDemoConnection(object):
         
     def init(self, target):
         PM.log('Initializing CU for target: ' + str(target), self._log_id)
+        response = []
         if target == 1 or target == 3:
             response = [0x80, 0xF0, 0x10, 0x69, 0xFF, 0xA2, 0x10, 0x02, 0x4D, 0x12, 0x04, 0x40, 0x06, 0xF3, 0xFA, 0xC9, 0x8E, 0x22, 0x04, 0x02, 0xAC, 0x00, 0x00, 0x00, 0x60, 0xCE, 0x54, 0xF8, 0xB9, 0x84, 0x00, 0x6C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x45, 0x1F, 0x30, 0x80, 0xF0, 0x20, 0x1F, 0x02, 0x43, 0xFB, 0x00, 0xF1, 0xC1, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26]
         if target == 2:

+ 115 - 127
pimonitor/PMMain.py

@@ -1,147 +1,135 @@
 # -*- coding: utf-8 -*-
 
-'''
+"""
 Created on 29-03-2013
 
 @author: citan
-'''
+"""
 
-import array
 import os
 import os.path
 import time
 import cPickle as pickle
+import platform
 
 from pimonitor.PM import PM
 from pimonitor.PMConnection import PMConnection
 from pimonitor.PMDemoConnection import PMDemoConnection
-from pimonitor.PMPacket import PMPacket
-from pimonitor.PMParameter import PMParameter
-from pimonitor.PMUtils import PMUtils
 from pimonitor.PMXmlParser import PMXmlParser
-
 from pimonitor.ui.PMScreen import PMScreen
 from pimonitor.ui.PMSingleWindow import PMSingleWindow
 
+
 if __name__ == '__main__':
 
-	from evdev import InputDevice, list_devices
-	devices = map(InputDevice, list_devices())
-	eventX = ""
-	for dev in devices:
-			if dev.name == "ADS7846 Touchscreen":
-				eventX = dev.fn
-
-	os.environ["SDL_FBDEV"] = "/dev/fb1"
-	os.environ["SDL_MOUSEDRV"] = "TSLIB"
-	os.environ["SDL_MOUSEDEV"] = eventX
-
-	screen = PMScreen()
-	log_id = PM.log('Application started')
-	
-	screen.render()
-	
-	parser = PMXmlParser();
-
-	supported_parameters = []
-	
-	if os.path.isfile("data/data.pkl"):
-		input = open("data/data.pkl", "rb")
-		defined_parameters = pickle.load(input)
-		input.close()
-	else:
-		defined_parameters = parser.parse("logger_METRIC_EN_v263.xml")
-		output = open("data/data.pkl", "wb")
-		pickle.dump(defined_parameters, output, -1)
-		output.close()		
-
-	connection = PMConnection()
-	#connection = PMDemoConnection()
-	while True:
-		try:
-			connection.open()
-			ecu_packet = connection.init(1)				
-			tcu_packet = connection.init(2)
-						
-			if ecu_packet == None or tcu_packet == None:
-				PM.log("Can't get initial data", log_id)
-				continue;
-			PM.log("ECU ROM ID: " + ecu_packet.get_rom_id())
-			PM.log("TCU ROM ID: " + tcu_packet.get_rom_id())
-			for p in defined_parameters:
-				if (p.get_target() & 0x1 == 0x1) and p.is_supported(ecu_packet.to_bytes()[4:]):
-					if not filter(lambda x: x.get_id() == p.get_id(), supported_parameters):
-						p.switch_to_ecu_id(ecu_packet.get_rom_id())
-						supported_parameters.append(p)
-
-			for p in defined_parameters:
-				if ((p.get_target() & 0x2 == 0x2) or (p.get_target() & 0x1 == 0x1)) and p.is_supported(tcu_packet.to_bytes()[4:]):
-					if not filter(lambda x: x.get_id() == p.get_id(), supported_parameters):
-						p.switch_to_ecu_id(tcu_packet.get_rom_id())
-						supported_parameters.append(p)
-
-			for p in defined_parameters:				
-				p_deps = p.get_dependencies();
-				if not p_deps:
-					continue
-
-				deps_found = () 
-				for dep in p_deps:
-					deps_found = filter(lambda x: x.get_id() == dep, supported_parameters)
-					if not deps_found:
-						break
-
-					if len(deps_found) > 1:
-						raise Exception('duplicated dependencies', deps_found) 
-									
-					p.add_parameter(deps_found[0])
-
-				if deps_found: 
-					supported_parameters.append(p) 					
-				
-			# each ID must be in a form P01 - first letter, then a number
-			# TODO fixme for 263 logger definition
-			# supported_parameters.sort(key=lambda p: int(p.get_id()[1:]), reverse=False)
-			
-			for p in supported_parameters:			
-				window = PMSingleWindow(p)
-				screen.add_window(window)
-
-			screen.next_window()
-			
-			while True:
-				window = screen.get_window()
-				param = window.get_parameter()
-				parameters = param.get_parameters()
-				if parameters:
-					packets = connection.read_parameters(parameters)
-					window.set_packets(packets)
-				else:
-					packet = connection.read_parameter(param)
-					window.set_packets([packet])
-				
-				#ecu_response_packets = connection.read_parameters(ecu_params)
-				#tcu_response_packets = connection.read_parameters(tcu_params)
-
-				#param_no = 0
-				#for ecu_packet in ecu_response_packets:
-				#	param = ecu_params[param_no]
-				#	window.set_value(param, ecu_packet)
-				#	param_no += 1
-
-				#param_no = 0
-				#for tcu_packet in tcu_response_packets:
-				#	param = tcu_params[param_no]
-				#	window.set_value(param, tcu_packet)
-				#	param_no += 1
-
-				screen.render()
-
-		except IOError as e:
-			PM.log('I/O error: {0} {1}'.format(e.errno, e.strerror), log_id)
-			if connection != None:
-				connection.close()
-				time.sleep(3)
-			continue
-
-	screen.close()
+    print platform.system()
+
+    if platform.system() == "Linux":
+        from evdev import InputDevice, list_devices
+
+        devices = map(InputDevice, list_devices())
+        eventX = ""
+        for dev in devices:
+            if dev.name == "ADS7846 Touchscreen":
+                eventX = dev.fn
+
+        os.environ["SDL_FBDEV"] = "/dev/fb1"
+        os.environ["SDL_MOUSEDRV"] = "TSLIB"
+        os.environ["SDL_MOUSEDEV"] = eventX
+
+    screen = PMScreen()
+    log_id = PM.log('Application started')
+
+    screen.render()
+
+    parser = PMXmlParser()
+
+    supported_parameters = []
+
+    if os.path.isfile("data/data.pkl"):
+        serializedDataFile = open("data/data.pkl", "rb")
+        defined_parameters = pickle.load(serializedDataFile)
+        serializedDataFile.close()
+    else:
+        defined_parameters = parser.parse("logger_METRIC_EN_v263.xml")
+    # output = open("data/data.pkl", "wb")
+    #pickle.dump(defined_parameters, output, -1)
+    #output.close()
+
+    if platform.system() == "Linux":
+        connection = PMConnection()
+    else:
+        connection = PMDemoConnection()
+
+    while True:
+        try:
+            connection.open()
+            ecu_packet = connection.init(1)
+            tcu_packet = connection.init(2)
+
+            if ecu_packet is None or tcu_packet is None:
+                PM.log("Can't get initial data", log_id)
+                continue
+            PM.log("ECU ROM ID: " + ecu_packet.get_rom_id())
+            PM.log("TCU ROM ID: " + tcu_packet.get_rom_id())
+            for p in defined_parameters:
+                if (p.get_target() & 0x1 == 0x1) and p.is_supported(ecu_packet.to_bytes()[4:]):
+                    if not filter(lambda x: x.get_id() == p.get_id(), supported_parameters):
+                        p.switch_to_ecu_id(ecu_packet.get_rom_id())
+                        supported_parameters.append(p)
+
+            for p in defined_parameters:
+                if ((p.get_target() & 0x2 == 0x2) or (p.get_target() & 0x1 == 0x1)) and p.is_supported(
+                        tcu_packet.to_bytes()[4:]):
+                    if not filter(lambda x: x.get_id() == p.get_id(), supported_parameters):
+                        p.switch_to_ecu_id(tcu_packet.get_rom_id())
+                        supported_parameters.append(p)
+
+            for p in defined_parameters:
+                p_deps = p.get_dependencies()
+                if not p_deps:
+                    continue
+
+                deps_found = ()
+                for dep in p_deps:
+                    deps_found = filter(lambda x: x.get_id() == dep, supported_parameters)
+                    if not deps_found:
+                        break
+
+                    if len(deps_found) > 1:
+                        raise Exception('duplicated dependencies', deps_found)
+
+                    p.add_parameter(deps_found[0])
+
+                if deps_found:
+                    supported_parameters.append(p)
+
+            supported_parameters = sorted(supported_parameters)
+
+            for p in supported_parameters:
+                window = PMSingleWindow(p)
+                screen.add_window(window)
+
+            screen.next_window()
+
+            while True:
+                window = screen.get_window()
+                param = window.get_parameter()
+                parameters = param.get_parameters()
+                if parameters:
+                    packets = connection.read_parameters(parameters)
+                    window.set_packets(packets)
+                else:
+                    packet = connection.read_parameter(param)
+                    window.set_packets([packet])
+
+                screen.render()
+
+        except IOError as e:
+            PM.log('I/O error: {0} {1}'.format(e.errno, e.strerror), log_id)
+            if connection is not None:
+                connection.close()
+                time.sleep(3)
+            continue
+
+    screen.close()

+ 113 - 112
pimonitor/PMPacket.py

@@ -1,120 +1,121 @@
-'''
+"""
 Created on 13-04-2013
 
 @author: citan
-'''
+"""
 
 import array
-import binascii
-import collections
+
 
 class PMPacket(object):
-	'''
+    """
 	classdocs
-	'''
-# 0x80
-# destination byte
-# source byte
-# data size byte
-# ...
-# checksum byte sum of every byte in packet (incl. header)
-
-	_header_byte = 0x80
-	_valid_bytes = [0xFF, 0xA8, 0xE8]
-	
-	def __init__(self, dst, src, data):
-		self._dst = dst
-		self._src = src
-		self._data = data
-
-	@classmethod
-	def from_array(cls, data):
-		validate = PMPacket.is_valid(data)
-		if (not validate[0]):
-			raise Exception('packet', validate[1])
-
-		dst = data[1]
-		src = data[2]
-		data = data[4:-1]
-		return cls(dst, src, data)
-
-	@classmethod
-	def is_valid(cls, data):
-		# TODO: check E8
-		valid = True
-		msg = ""
-
-		valid = valid and (len(data) > 5)
-		msg += "invalid length (too short), " if (not valid) else ""
-
-		valid = valid and (data[0] == PMPacket._header_byte)
-		msg += "invalid header, " if (not valid) else ""
-
-		
-		#valid = data[4] in PMPacket._valid_bytes
-		#msg += "invalid header, expected one of " + ', '.join(hex(s) for s in PMPacket._valid_bytes) +", got: " + hex(data[4]) + ", " if (not valid) else ""  
-		#valid = valid and ((data[1] == 0x10) or (data[1] == 0xf0))
-		#valid = valid and ((data[2] == 0x10) or (data[2] == 0xf0))
-		#valid = valid and (data[1] != data[2])
-		#msg += "invalid source/target, " if (not valid) else ""
-
-		current_len = len(data)
-		expected_len = 5 + data[3]
-		valid = valid and (current_len == expected_len)
-		msg += "invalid length (is: " + str(current_len) + ", expected: " + str(expected_len) + "), " if (not valid) else ""
-
-		checksum = 0
-		for i in range(0, len(data) - 1):
-			checksum = (checksum + data[i]) & 0xFF
-
-		valid = valid and (checksum == data[-1])
-		msg += "invalid checksum (is " + str(checksum) + ", expected: " + str(data[-1]) + "), " if (not valid) else ""
-
-		return valid, msg
-
-	def is_equal(self, packet):
-		return self.to_bytes() == packet.to_bytes()
-
-	def to_bytes(self):
-		length = len(self._data)
-
-		packet = [self._header_byte, self._dst, self._src, length]
-		packet.extend(self._data)
-
-		checksum = 0
-		for b in packet:
-			checksum = (checksum + b) & 0xFF
-
-		packet.append(checksum)
-		return packet
-
-	def to_string(self):
-		return array.array('B', self.to_bytes()).tostring()
-
-	def dump(self):
-		return "["+ ', '.join(("0x%0.2X" % s) for s in self.to_bytes()) + "], dst: " + hex(self._dst) + ", src: " + hex(self._src) + ", len: " + str(len(self._data))
-
-	def get_data(self):
-		return self._data
-
-	def get_destination(self):
-		return self._dst
-
-	def get_source(self):
-		return self._src
-	
-	def get_rom_id(self):
-		return PMPacket.extract_rom_id(self._data)
-		
-	@classmethod
-	def extract_rom_id(cls, data):
-		if data[0] != 0xFF:
-			raise Exception('packet', "not valid init response: " + hex(data[0]) + " instead 0xFF")
-		if len(data) < 9:
-			raise Exception('packet', "not valid init response")
-		rom_id = ((data[4] << 32) | (data[5] << 24) | (data[6] << 16) | (data[7] << 8) | (data[8])) & 0xFFFFFFFFFF
-		return hex(rom_id).lstrip("0x").upper()
-
-	@classmethod
-	def dump_header(cls, data):
-		print("header ["+ ', '.join(hex(s) for s in data) +"], len: " + str(len(data)))
+	"""
+    # 0x80
+    # destination byte
+    # source byte
+    # data size byte
+    # ...
+    # checksum byte sum of every byte in packet (incl. header)
+
+    _header_byte = 0x80
+    _valid_bytes = [0xFF, 0xA8, 0xE8]
+
+    def __init__(self, dst, src, data):
+        self._dst = dst
+        self._src = src
+        self._data = data
+
+    @classmethod
+    def from_array(cls, data):
+        validate = PMPacket.is_valid(data)
+        if not validate[0]:
+            raise Exception('packet', validate[1])
+
+        dst = data[1]
+        src = data[2]
+        data = data[4:-1]
+        return cls(dst, src, data)
+
+    @classmethod
+    def is_valid(cls, data):
+        # TODO: check E8
+        valid = True
+        msg = ""
+
+        valid = valid and (len(data) > 5)
+        msg += "invalid length (too short), " if (not valid) else ""
+
+        valid = valid and (data[0] == PMPacket._header_byte)
+        msg += "invalid header, " if (not valid) else ""
+
+
+        # valid = data[4] in PMPacket._valid_bytes
+        # msg += "invalid header, expected one of " + ', '.join(hex(s) for s in PMPacket._valid_bytes) +", got: " + hex(data[4]) + ", " if (not valid) else ""
+        #valid = valid and ((data[1] == 0x10) or (data[1] == 0xf0))
+        #valid = valid and ((data[2] == 0x10) or (data[2] == 0xf0))
+        #valid = valid and (data[1] != data[2])
+        #msg += "invalid source/target, " if (not valid) else ""
+
+        current_len = len(data)
+        expected_len = 5 + data[3]
+        valid = valid and (current_len == expected_len)
+        msg += "invalid length (is: " + str(current_len) + ", expected: " + str(expected_len) + "), " if (
+            not valid) else ""
+
+        checksum = 0
+        for i in range(0, len(data) - 1):
+            checksum = (checksum + data[i]) & 0xFF
+
+        valid = valid and (checksum == data[-1])
+        msg += "invalid checksum (is " + str(checksum) + ", expected: " + str(data[-1]) + "), " if (not valid) else ""
+
+        return valid, msg
+
+    def is_equal(self, packet):
+        return self.to_bytes() == packet.to_bytes()
+
+    def to_bytes(self):
+        length = len(self._data)
+
+        packet = [self._header_byte, self._dst, self._src, length]
+        packet.extend(self._data)
+
+        checksum = 0
+        for b in packet:
+            checksum = (checksum + b) & 0xFF
+
+        packet.append(checksum)
+        return packet
+
+    def to_string(self):
+        return array.array('B', self.to_bytes()).tostring()
+
+    def dump(self):
+        return "[" + ', '.join(("0x%0.2X" % s) for s in self.to_bytes()) + "], dst: " + hex(
+            self._dst) + ", src: " + hex(self._src) + ", len: " + str(len(self._data))
+
+    def get_data(self):
+        return self._data
+
+    def get_destination(self):
+        return self._dst
+
+    def get_source(self):
+        return self._src
+
+    def get_rom_id(self):
+        return PMPacket.extract_rom_id(self._data)
+
+    @classmethod
+    def extract_rom_id(cls, data):
+        if data[0] != 0xFF:
+            raise Exception('packet', "not valid init response: " + hex(data[0]) + " instead 0xFF")
+        if len(data) < 9:
+            raise Exception('packet', "not valid init response")
+        rom_id = ((data[4] << 32) | (data[5] << 24) | (data[6] << 16) | (data[7] << 8) | (data[8])) & 0xFFFFFFFFFF
+        return hex(rom_id).lstrip("0x").upper()
+
+    @classmethod
+    def dump_header(cls, data):
+        print("header [" + ', '.join(hex(s) for s in data) + "], len: " + str(len(data)))

+ 180 - 178
pimonitor/PMParameter.py

@@ -1,187 +1,189 @@
-'''
+"""
 Created on 29-03-2013
 
 @author: citan
-'''
+"""
 
 import re
 
 from pimonitor.PMPacket import PMPacket
 
+
 class PMParameter(object):
-	'''
-	classdocs
-	'''
-
-	def __init__(self, pid, name, desc, byte_index, bit_index, target):
-		'''
-		Constructor
-		'''
-		self._id = pid
-		self._name = name
-		self._desc = desc
-		self._byte_index = byte_index
-		self._bit_index = bit_index
-		self._target = target
-		self._conversions = []
-		self._dependencies = []
-		self._parameters = []
-		self._address = 0
-		self._address_length = 1
-		self._ecu_ids = {}
-
-	def get_id(self):
-		return self._id;
-
-	def set_address(self, address, length):
-		self._address = address
-		self._address_length = length
-
-	def get_address(self):
-		return self._address
-
-	def get_address_length(self):
-		return self._address_length
-
-	def get_target(self):
-		return self._target
-
-	def get_name(self):
-		return self._name
-	
-	def add_conversion(self, conversion):
-		self._conversions.append(conversion)
-	
-	def add_dependency(self, dependency):
-		self._dependencies.append(dependency)
-
-	def get_dependencies(self):
-		return self._dependencies
-
-	def add_parameter(self, parameter):
-		self._parameters.append(parameter)
-
-	def get_parameters(self):
-		return self._parameters
-		
-	def init_ecu_id(self, ecu_id):
-		self._ecu_ids[ecu_id] = []
-		
-	def get_ecu_id(self, ecu_id):
-		return self._ecu_ids[ecu_id]
-		
-	def get_calculated_value(self, packets, unit=None):
-		value = ""
-		local_vars = locals()
-		
-		if len(self._conversions) > 0 and unit == None:
-			unit = self._conversions[0][0]
-			
-		for conversion in self._conversions:
-			currunit = conversion[0]
-			expr = conversion[1]
-			value_format = conversion[2]
-			conversion_map = {}		
-			if unit == currunit:
-				param_pairs = re.findall(r'\[([^]]*)\]',expr)
-				for pair in param_pairs:
-					attributes = pair.split(":")
-					key = attributes[0]
-					unit = attributes[1] 
-					expr = expr.replace("[" + key + ":" + unit + "]", key)
-					conversion_map.update({key:unit})
-				
-				param_no = 0
-				for packet in packets:
-					param = self._parameters[param_no];
-					if param.get_id() in conversion_map:
-						conversion_unit = conversion_map[param.get_id()]
-					else:
-						conversion_unit = None
-					
-					value = param.get_value(packet, conversion_unit);
-
-					local_vars[param.get_id()] = float(value)
-					param_no += 1
-		
-				try:
-					value = eval(expr)
-				except:
-					value = 0.0
-
-				format_tokens = value_format.split(".")
-				output_format = "%.0f"
-				if len(format_tokens) > 1:
-					output_format = "%." + str(len(format_tokens[1])) + "f"
-
-				value = output_format % value
-
-		return value
-
-	def get_value(self, packet, unit=None):
-		value = ""
-		
-		if len(self._conversions) > 0 and unit == None:
-			unit = self._conversions[0][0]
-			
-		for conversion in self._conversions:
-			currunit = conversion[0]
-			expr = conversion[1]
-			value_format = conversion[2]
-			if unit == currunit:
-				# ignore 0xe8
-				index = 1
-				x = 0
-				value_bytes = packet.get_data()[index:index + self._address_length]
-				if self._address_length == 1:
-					x = value_bytes[0]
-
-				if self._address_length == 2:
-					x = (value_bytes[0] << 8) | value_bytes[1]
-					
-				if self._address_length == 4:
-					x = (value_bytes[0] << 24) | (value_bytes[1] << 16) | (value_bytes[2] << 8) | value_bytes[2]
-				
-				x = float(x)
-				
-				try:
-					value = eval(expr)
-				except:
-					value = 0.0
-					
-				format_tokens = value_format.split(".")
-				output_format = "%.0f"
-				if len(format_tokens) > 1:
-					output_format = "%." + str(len(format_tokens[1])) + "f"
-
-				value = output_format % value
-				
-		return value
-	
-	def get_default_unit(self):
-		if len(self._conversions) > 0:
-			return self._conversions[0][0]
-		return ""
-		
-	def switch_to_ecu_id(self, ecu_id):
-		if ecu_id in self._ecu_ids:
-			ecu_id_data = self._ecu_ids[ecu_id]
-			self._address = ecu_id_data[0]
-			self._address_length = ecu_id_data[1]
-			if self._address_length == 0:
-				self._address_length = 1
-	
-	def is_supported(self, data):
-		if self._byte_index != "none" and self._bit_index != "none" and len(data) - 1 > self._byte_index:
-			cubyte = data[1 + self._byte_index]
-			bitmask = 1 << self._bit_index
-			return cubyte & bitmask == bitmask
-		elif self._ecu_ids != None:
-			return PMPacket.extract_rom_id(data) in self._ecu_ids
-		else:
-			return False
-
-	def to_string(self):
-		return "Param: id=" + self._id + ", name=" + self._name + ", desc=" + self._desc + ", byte=" + str(self._byte_index) + \
-		", bit=" + str(self._bit_index) + ", target=" + str(self._target) + ", conversions=" + '[%s]' % ', '.join(map(str, self._conversions)) + \
-		", address=" + hex(self._address) + "[" + str(self._address_length) + "]" 
+    """
+    classdocs
+    """
+
+    def __init__(self, pid, name, desc, byte_index, bit_index, target):
+        """
+        Constructor
+        """
+        self._id = pid
+        self._name = name
+        self._desc = desc
+        self._byte_index = byte_index
+        self._bit_index = bit_index
+        self._target = target
+        self._conversions = []
+        self._dependencies = []
+        self._parameters = []
+        self._address = 0
+        self._address_length = 0
+        self._ecu_ids = {}
+
+    def get_id(self):
+        return self._id
+
+    def set_address(self, address, length):
+        self._address = address
+        self._address_length = length
+
+    def get_address(self):
+        return self._address
+
+    def get_address_length(self):
+        return self._address_length
+
+    def get_target(self):
+        return self._target
+
+    def get_name(self):
+        return self._name
+
+    def add_conversion(self, conversion):
+        self._conversions.append(conversion)
+
+    def add_dependency(self, dependency):
+        self._dependencies.append(dependency)
+
+    def get_dependencies(self):
+        return self._dependencies
+
+    def add_parameter(self, parameter):
+        self._parameters.append(parameter)
+
+    def get_parameters(self):
+        return self._parameters
+
+    def init_ecu_id(self, ecu_id):
+        self._ecu_ids[ecu_id] = []
+
+    def get_ecu_id(self, ecu_id):
+        return self._ecu_ids[ecu_id]
+
+    def get_calculated_value(self, packets, unit=None):
+        value = ""
+        local_vars = locals()
+
+        if len(self._conversions) > 0 and unit is None:
+            unit = self._conversions[0][0]
+
+        for conversion in self._conversions:
+            currunit = conversion[0]
+            expr = conversion[1]
+            value_format = conversion[2]
+            conversion_map = {}
+            if unit == currunit:
+                param_pairs = re.findall(r'\[([^]]*)\]', expr)
+                for pair in param_pairs:
+                    attributes = pair.split(":")
+                    key = attributes[0]
+                    unit = attributes[1]
+                    expr = expr.replace("[" + key + ":" + unit + "]", key)
+                    conversion_map.update({key: unit})
+
+                param_no = 0
+                for packet in packets:
+                    param = self._parameters[param_no]
+                    if param.get_id() in conversion_map:
+                        conversion_unit = conversion_map[param.get_id()]
+                    else:
+                        conversion_unit = None
+
+                    if param.get_dependencies():
+                        return "DEPS :("
+                    else:
+                        value = param.get_value(packet, conversion_unit)
+                        local_vars[param.get_id()] = float(value)
+                    param_no += 1
+
+                try:
+                    value = eval(expr)
+                except (SyntaxError, ZeroDivisionError):
+                    value = 0.0
+
+                format_tokens = value_format.split(".")
+                output_format = "%.0f"
+                if len(format_tokens) > 1:
+                    output_format = "%." + str(len(format_tokens[1])) + "f"
+
+                value = output_format % value
+
+        return value
+
+    # noinspection PyUnusedLocal
+    def get_value(self, packet, unit=None):
+        value = ""
+
+        if len(self._conversions) > 0 and unit is None:
+            unit = self._conversions[0][0]
+
+        for conversion in self._conversions:
+            currunit = conversion[0]
+            expr = conversion[1]
+            value_format = conversion[2]
+            if unit == currunit:
+                # ignore 0xe8
+                index = 1
+                x = 0
+                value_bytes = packet.get_data()[index:index + self._address_length]
+                if self._address_length == 1:
+                    x = value_bytes[0]
+
+                if self._address_length == 2:
+                    x = (value_bytes[0] << 8) | value_bytes[1]
+
+                if self._address_length == 4:
+                    x = (value_bytes[0] << 24) | (value_bytes[1] << 16) | (value_bytes[2] << 8) | value_bytes[2]
+
+                try:
+                    value = eval(expr)
+                except (SyntaxError, ZeroDivisionError):
+                    value = 0.0
+
+                format_tokens = value_format.split(".")
+                output_format = "%.0f"
+                if len(format_tokens) > 1:
+                    output_format = "%." + str(len(format_tokens[1])) + "f"
+
+                value = output_format % value
+
+        return value
+
+    def get_default_unit(self):
+        if len(self._conversions) > 0:
+            return self._conversions[0][0]
+        return ""
+
+    def switch_to_ecu_id(self, ecu_id):
+        if ecu_id in self._ecu_ids:
+            ecu_id_data = self._ecu_ids[ecu_id]
+            self._address = ecu_id_data[0]
+            self._address_length = ecu_id_data[1]
+
+    def is_supported(self, data):
+        if self._byte_index != "none" and self._bit_index != "none" and len(data) - 1 > self._byte_index:
+            cubyte = data[1 + self._byte_index]
+            bitmask = 1 << self._bit_index
+            return cubyte & bitmask == bitmask
+        elif self._ecu_ids is not None:
+            return PMPacket.extract_rom_id(data) in self._ecu_ids
+        else:
+            return False
+
+    def to_string(self):
+        return "Param: id=" + self._id + ", name=" + self._name + ", desc=" + self._desc + ", byte=" + str(
+            self._byte_index) + \
+               ", bit=" + str(self._bit_index) + ", target=" + str(
+            self._target) + ", conversions=" + '[%s]' % ', '.join(map(str, self._conversions)) + \
+               ", address=" + hex(self._address) + "[" + str(self._address_length) + "]"

+ 60 - 59
pimonitor/PMUtils.py

@@ -1,73 +1,74 @@
-'''
+"""
 Created on 13-04-2013
 
 @author: citan
-'''
+"""
 
 import os
 from pimonitor.PM import PM
 
+
 class PMUtils(object):
-	'''
+    """
 	classdocs
-	'''
+	"""
+
+
+    # Return CPU temperature as a character string
+    @classmethod
+    def get_cpu_temperature(cls):
+        res = os.popen('vcgencmd measure_temp').readline()
+        return res.replace("temp=", "").replace("'C\n", "")
+
+    # Return RAM information (unit=kb) in a list
+    # Index 0: total RAM
+    # Index 1: used RAM
+    # Index 2: free RAM
+    @classmethod
+    def get_ram_info(cls):
+        p = os.popen('free')
+        i = 0
+        while 1:
+            i += 1
+            line = p.readline()
+            if i == 2:
+                return line.split()[1:4]
+
+    # Return % of CPU used by user as a character string
+    @classmethod
+    def get_cpu_use(cls):
+        return str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip())
 
-	
-	# Return CPU temperature as a character string
-	@classmethod    
-	def get_cpu_temperature(cls):
-		res = os.popen('vcgencmd measure_temp').readline()
-		return(res.replace("temp=", "").replace("'C\n", ""))
+    # Return information about disk space as a list (unit included)
+    # Index 0: total disk space
+    # Index 1: used disk space
+    # Index 2: remaining disk space
+    # Index 3: percentage of disk used
+    @classmethod
+    def get_disk_space(cls):
+        p = os.popen("df -h /")
+        i = 0
+        while 1:
+            i += 1
+            line = p.readline()
+            if i == 2:
+                return line.split()[1:5]
 
-	# Return RAM information (unit=kb) in a list                                        
-	# Index 0: total RAM                                                                
-	# Index 1: used RAM                                                                 
-	# Index 2: free RAM
-	@classmethod                                                                 
-	def get_ram_info(cls):
-		p = os.popen('free')
-		i = 0
-		while 1:
-			i = i + 1
-			line = p.readline()
-			if i == 2:
-				return(line.split()[1:4])
+    @classmethod
+    def log_os_stats(cls):
+        try:
+            cpu_temp = PMUtils.get_cpu_temperature()
+            if len(cpu_temp) > 0:
+                PM.log("CPU temp: " + cpu_temp)
 
-	# Return % of CPU used by user as a character string
-	@classmethod                                
-	def get_cpu_use(cls):
-		return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))
+            ram_stats = PMUtils.get_ram_info()
+            if len(ram_stats) == 3:
+                ram_free = round(int(ram_stats[2]) / 1000, 1)
+                PM.log("RAM free: " + str(ram_free))
 
-	# Return information about disk space as a list (unit included)                     
-	# Index 0: total disk space                                                         
-	# Index 1: used disk space                                                          
-	# Index 2: remaining disk space                                                     
-	# Index 3: percentage of disk used
-	@classmethod                                                  
-	def get_disk_space(cls):
-		p = os.popen("df -h /")
-		i = 0
-		while 1:
-			i = i + 1
-			line = p.readline()
-			if i == 2:
-				return(line.split()[1:5])
+            cpu_usage = PMUtils.get_cpu_use()
+            if len(cpu_usage) > 0:
+                PM.log("CPU usage: " + str(cpu_usage))
 
-	@classmethod
-	def log_os_stats(cls):
-		try:
-			cpu_temp = PMUtils.get_cpu_temperature()
-			if len(cpu_temp) > 0:
-				PM.log("CPU temp: " + cpu_temp)
-				
-			ram_stats = PMUtils.get_ram_info()
-			if len(ram_stats) == 3:
-				ram_free = round(int(ram_stats[2]) / 1000,1)
-				PM.log("RAM free: " + str(ram_free))
-				
-			cpu_usage = PMUtils.get_cpu_use()
-			if len(cpu_usage) > 0:
-				PM.log("CPU usage: " + str(cpu_usage))
-				
-		except IOError:
-			pass
+        except IOError:
+            pass

+ 170 - 162
pimonitor/PMXmlParser.py

@@ -1,8 +1,8 @@
-'''
+"""
 Created on 29-03-2013
 
 @author: citan
-'''
+"""
 
 import xml.sax
 import os.path
@@ -13,8 +13,8 @@ from pimonitor.PMParameter import PMParameter
 # TODO: dependencies
 # TODO: ecuparams
 
-#<parameter id="P1" name="Engine Load (Relative)" desc="P1" ecubyteindex="8" ecubit="7" target="1">
-#    <address>0x000007</address>
+# <parameter id="P1" name="Engine Load (Relative)" desc="P1" ecubyteindex="8" ecubit="7" target="1">
+# <address>0x000007</address>
 #    <conversions>
 #        <conversion units="%" expr="x*100/255" format="0.00" />
 #    </conversions>
@@ -29,165 +29,173 @@ from pimonitor.PMParameter import PMParameter
 # <switch id="S71" name="Clear Memory Terminal" desc="(E) S71" byte="0x000061" bit="0" ecubyteindex="19" target="1" />
 
 class PMXmlParser(xml.sax.ContentHandler):
-	'''
+    """
 	classdocs
-	'''
+	"""
 
 
-	def __init__(self):
-		'''
+    def __init__(self):
+        """
 		Constructor
-		'''
-		xml.sax.ContentHandler.__init__(self)
-		
-	def parse(self, file_name):
-		self._parameters = set()
-		self._parameter = None
-		self._element_no = 0
-		self._characters = ''
-		self._ecu_id = None
-		
-		self._message = "Parsing XML data"
-		self._log_id = PM.log(self._message)
-		source = open(os.path.join("data", file_name))
-		xml.sax.parse(source, self)
-		PM.log(self._message + " [DONE]", self._log_id)
-		
-		return self._parameters
-
-	def startElement(self, name, attrs):
-		if name == "parameter":
-			byte_index = "none"
-			bit_index = "none"
-
-			for (k,v) in attrs.items():
-				if k == "id":
-					pid = v
-				if k == "name":
-					name = v
-				if k == "desc":
-					desc = v
-				if k == "ecubyteindex":
-					byte_index = int(v)
-				if k == "ecubit":
-					bit_index = int(v)
-				if k == "target":
-					target = int(v)
-
-			self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)
-
-		if name == "switch":
-			byte_index = "none"
-			bit_index = "none"
-
-			for (k,v) in attrs.items():
-				if k == "id":
-					pid = v
-				if k == "name":
-					name = v
-				if k == "desc":
-					desc = v
-				if k == "ecubyteindex":
-					byte_index = int(v)
-				if k == "bit":
-					bit_index = int(v)
-				if k == "target":
-					target = int(v)
-				if k == "byte":
-					address = v
-
-			self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)
-			self._parameter.set_address(int(address, 16), 1)
-			
-	   	if name == "ecuparam":
-			byte_index = "none"
-			bit_index = "none"
-
-			for (k,v) in attrs.items():
-				if k == "id":
-					pid = v
-				if k == "name":
-					name = v
-				if k == "desc":
-					desc = v
-				if k == "target":
-					target = int(v)
-					
-			self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)
-							 
-		if name == "address":
-			self._addrlen = 1
-			for (k,v) in attrs.items():
-				if k == "length":
-					self._addrlen = int(v)
-					
-		if name == "depends":
-			self._addrlen = 0
-
-		if name == "ref":
-			for (k,v) in attrs.items():
-				if k == "parameter":
-					self._parameter.add_dependency(v)
-			
-		if name == "conversion":
-			for (k,v) in attrs.items():
-				if k == "units":
-					units = v
-				if k == "expr":
-					expr = v
-				if k == "format":
-					value_format = v
-					
-			self._parameter.add_conversion([units, expr, value_format])
-		
-		if name == "ecu":
-			for (k,v) in attrs.items():
-				if k == "id":
-					self._parameter.init_ecu_id(v)
-					self._ecu_id = self._parameter.get_ecu_id(v)
-					
-		self._name = name
-
-	def characters(self, content):
-		self._characters = self._characters + content
-		
-	def endElement(self, name):
-		if name == "parameter":
-			self._parameters.add(self._parameter)
-			self._parameter = None
-			self._addrlen = None
-			
-		if name == "ecuparam":
-			self._parameters.add(self._parameter)
-			self._parameter = None
-			self._addrlen = None
-		
-		if name == "switch":
-			#self._parameters.add(self._parameter)
-			self._parameter = None
-			self._addrlen = None
-		
-		if name == "address":
-			self._characters = self._characters.strip()
-			if len(self._characters.strip()) > 0 and self._name == "address" and self._parameter != None:			
-				if self._ecu_id == None:
-					self._parameter.set_address(int(self._characters, 16), self._addrlen)
-				else:					
-					self._ecu_id.append(int(self._characters, 16))
-					self._ecu_id.append(self._addrlen)
-
-			self._addrlen = 0
-			self._characters = ''
-
-		if name == "ecu":
-			self._ecu_id = None
-
-		if name == "depends":
-			pass
-
-		self._name = ""
-		
-		self._element_no += 1
-		
-		if self._element_no % 1000 == 0:
-			PM.log(self._message + " " + str(self._element_no) + " elements", self._log_id)
+		"""
+        xml.sax.ContentHandler.__init__(self)
+
+    def parse(self, file_name):
+        self._parameters = set()
+        self._parameter = None
+        self._element_no = 0
+        self._characters = ''
+        self._ecu_id = None
+
+        self._message = "Parsing XML data"
+        self._log_id = PM.log(self._message)
+        source = open(os.path.join("data", file_name))
+        xml.sax.parse(source, self)
+        PM.log(self._message + " [DONE]", self._log_id)
+
+        return self._parameters
+
+    def startElement(self, name, attrs):
+        pid = None
+        desc = None
+        target = None
+        address = None
+        units = None
+        expr = None
+        value_format = None
+
+        if name == "parameter":
+            byte_index = "none"
+            bit_index = "none"
+
+            for (k, v) in attrs.items():
+                if k == "id":
+                    pid = v
+                if k == "name":
+                    name = v
+                if k == "desc":
+                    desc = v
+                if k == "ecubyteindex":
+                    byte_index = int(v)
+                if k == "ecubit":
+                    bit_index = int(v)
+                if k == "target":
+                    target = int(v)
+
+            self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)
+
+        if name == "switch":
+            byte_index = "none"
+            bit_index = "none"
+
+            for (k, v) in attrs.items():
+                if k == "id":
+                    pid = v
+                if k == "name":
+                    name = v
+                if k == "desc":
+                    desc = v
+                if k == "ecubyteindex":
+                    byte_index = int(v)
+                if k == "bit":
+                    bit_index = int(v)
+                if k == "target":
+                    target = int(v)
+                if k == "byte":
+                    address = v
+
+            self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)  #
+            self._parameter.set_address(int(address, 16), 1)
+
+        if name == "ecuparam":
+            byte_index = "none"
+            bit_index = "none"
+
+            for (k, v) in attrs.items():
+                if k == "id":
+                    pid = v
+                if k == "name":
+                    name = v
+                if k == "desc":
+                    desc = v
+                if k == "target":
+                    target = int(v)
+
+            self._parameter = PMParameter(pid, name, desc, byte_index, bit_index, target)
+
+        if name == "address":
+            self._addrlen = 1
+            for (k, v) in attrs.items():
+                if k == "length":
+                    self._addrlen = int(v)
+
+        if name == "depends":
+            self._addrlen = 0
+
+        if name == "ref":
+            for (k, v) in attrs.items():
+                if k == "parameter":
+                    self._parameter.add_dependency(v)
+
+        if name == "conversion":
+            for (k, v) in attrs.items():
+                if k == "units":
+                    units = v
+                if k == "expr":
+                    expr = v
+                if k == "format":
+                    value_format = v
+
+            self._parameter.add_conversion([units, expr, value_format])
+
+        if name == "ecu":
+            for (k, v) in attrs.items():
+                if k == "id":
+                    self._parameter.init_ecu_id(v)
+                    self._ecu_id = self._parameter.get_ecu_id(v)
+
+        self._name = name
+
+    def characters(self, content):
+        self._characters = self._characters + content
+
+    def endElement(self, name):
+        if name == "parameter":
+            self._parameters.add(self._parameter)
+            self._parameter = None
+            self._addrlen = 0
+
+        if name == "ecuparam":
+            self._parameters.add(self._parameter)
+            self._parameter = None
+            self._addrlen = 0
+
+        #if name == "switch":
+        #self._parameters.add(self._parameter)
+        #self._parameter = None
+        #self._addrlen = 0
+
+        if name == "address":
+            self._characters = self._characters.strip()
+            if len(self._characters.strip()) > 0 and self._name == "address" and self._parameter is not None:
+                if self._ecu_id is None:
+                    self._parameter.set_address(int(self._characters, 16), self._addrlen)
+                else:
+                    self._ecu_id.append(int(self._characters, 16))
+                    self._ecu_id.append(self._addrlen)
+
+            self._addrlen = 0
+            self._characters = ''
+
+        if name == "ecu":
+            self._ecu_id = None
+
+        if name == "depends":
+            pass
+
+        self._name = ""
+
+        self._element_no += 1
+
+        if self._element_no % 1000 == 0:
+            PM.log(self._message + " " + str(self._element_no) + " elements", self._log_id)

+ 228 - 219
pimonitor/ui/PMScreen.py

@@ -1,232 +1,241 @@
-'''
+"""
 Created on 18-04-2013
 
 @author: citan
-'''
+"""
 
-import pygame
-import os.path
 import os
 import sys
+import platform
+
+import pygame
 
 from pimonitor.PM import PM
 from pimonitor.PMUtils import PMUtils
 
+
 class PMScreen(object):
-	'''
+    """
 	classdocs
-	'''
-	LOG_FPS_EVENT = pygame.USEREVENT + 1
-	LOG_STATS_EVENT = LOG_FPS_EVENT + 1
-	ONE_SEC_EVENT = LOG_STATS_EVENT + 1
-	 
-	def __init__(self):
-		'''
+	"""
+    LOG_FPS_EVENT = pygame.USEREVENT + 1
+    LOG_STATS_EVENT = LOG_FPS_EVENT + 1
+    ONE_SEC_EVENT = LOG_STATS_EVENT + 1
+
+    def __init__(self):
+        """
 		Constructor
-		'''
-		pygame.init()
-		pygame.mouse.set_visible(False)
-		
-		# seems to suit RPi
-		self._color_depth = 16
-
-		pygame.display.set_mode((0, 0), pygame.FULLSCREEN, self._color_depth)
-		#pygame.display.set_mode((640, 480), 0, self._color_depth)
-		self._surface = pygame.display.get_surface()
-
-		self._clock = pygame.time.Clock()
-		
-		self._width = self._surface.get_width();
-		self._height = self._surface.get_height();
-		
-		self._subwindow_alpha = 200
-		
-		self._font_size = int(self._height / 14)
-		self._font = pygame.font.SysFont(pygame.font.get_default_font(), self._font_size)
-		self._font_aa = 0
-		self._fg_color = pygame.Color(255, 191, 0)
-		self._bg_color = pygame.Color(0, 0, 0)
-		self._dim_color = pygame.Color(200, 140, 0)
-		
-		self._log_lines = 4
-		self._log_msg_id = 0
-		self._log_surface = pygame.Surface((self._width / 2, self._font_size * self._log_lines), 0, self._color_depth)
-		self._log_surface.set_alpha(self._subwindow_alpha)
-		self._log_queue = []
-		
-		logger = PM()
-		logger.set(self.log)
-		
-		self._fps_log_id = 0
-		self._frame_no = 0
-		self.load_resources()
-		pygame.time.set_timer(PMScreen.LOG_FPS_EVENT, 10000)
-		pygame.time.set_timer(PMScreen.LOG_STATS_EVENT, 30000)
-		pygame.time.set_timer(PMScreen.ONE_SEC_EVENT, 1000)
-
-		self._window = None
-		self._windows = []
-		
-		self._pos_log_id = 0;
-		self._mouse_down_pos = (0, 0);
-		self._mouse_down_mark_timeout = 0
-		
-	def clear(self):
-		self._surface.fill(self._bg_color)
-
-	def load_resources(self):
-		self._bg_img = pygame.image.load(os.path.join('res', 'subaru_logo.png')).convert()
-		self._bg_img_rect = self._bg_img.get_rect()
-
-	def render(self):
-		self._clock.tick()
-		
-		for event in pygame.event.get():
-			if event.type == PMScreen.LOG_FPS_EVENT:
-				self._frame_no += 1
-				self._fps_log_id = PM.log("FPS %.2f" % self._clock.get_fps(), self._fps_log_id)
-
-			elif event.type == PMScreen.LOG_STATS_EVENT:
-				PMUtils.log_os_stats()				
-			elif event.type == pygame.QUIT:
-				self.close()
-				sys.exit()
-			
-			elif event.type == pygame.MOUSEBUTTONUP:
-				self._mouse_down_mark_timeout = 0
-				self._mouse_down_pos = pygame.mouse.get_pos();
-				self._pos_log_id = PM.log('Mouse up at: %s/%s' % pygame.mouse.get_pos(), self._pos_log_id);
-				if self._mouse_down_pos[0] < self._width / 2:
-					self.prev_window()
-				else:
-					self.next_window()
-			elif event.type == PMScreen.ONE_SEC_EVENT:
-				self._mouse_down_mark_timeout += 1
-
-		self.clear()
-		
-		if self._window == None:
-			self.render_bg()
-
-		if self._window != None:
-			self._window.render()
-			
-		self.render_log()
-
-		if self._mouse_down_mark_timeout < 2:
-			pygame.draw.circle(self._surface, self._dim_color, self._mouse_down_pos, 16);
-			
-		pygame.display.update()
-
-	def render_log(self):
-		self.purge_logs()
-		if len(self._log_queue) == 0:
-			return
-		
-		self._log_surface.fill(self._bg_color)
-		
-		log_pos = 0
-		for msg_entry in self._log_queue:
-			msg_entry[2] = msg_entry[2] + 1
-			message = msg_entry[1]
-			message_lbl = self._font.render(message, self._font_aa, self._fg_color, self._bg_color)
-			self._log_surface.blit(message_lbl, (0, log_pos))
-			log_pos += self._font_size
-		
-		self._surface.blit(self._log_surface, (0, self._height - self._log_surface.get_height()))
-		
-	def render_bg(self):		
-		#self._surface.blit(self._bg_img, self._bg_img_rect)
-		pass
-
-	def purge_oldest_log(self):
-		oldest = pygame.time.get_ticks()
-		
-		for log_entry in self._log_queue:
-			if log_entry[2] < oldest:
-				oldest = log_entry[2]
-				to_be_deleted = log_entry
-				
-		self._log_queue.remove(to_be_deleted)
-
-		
-	def purge_logs(self):
-		to_be_deleted = []
-
-		for log_entry in self._log_queue:
-			if pygame.time.get_ticks() - log_entry[2] > 5000:
-				to_be_deleted.append(log_entry)
-			
-		for log_entry in to_be_deleted:
-			self._log_queue.remove(log_entry)
-
-	def add_window(self, window):
-		self._windows.append(window);
-
-	def set_window(self, window):
-		if self._window != None:
-			self._window.set_surface(None)
-			
-		self._window = window
-		self._window.set_surface(self._surface)
-	
-	def get_window(self):
-		return self._window
-	
-	def next_window(self):
-		if not self._windows:
-			return
-
-		if self._window != None:
-			index = self._windows.index(self._window)
-		else:
-			index = -1
-			
-		new_index = (index + 1) % len(self._windows)
-		self.set_window(self._windows[new_index])
-		self.log_window(new_index)
-		
-	def prev_window(self):
-		if not self._windows:
-			return
-		
-		if self._window != None:
-			index = self._windows.index(self._window)
-		else:
-			index = 1
-			
-		new_index = (index - 1) % len(self._windows)		
-		self.set_window(self._windows[new_index])
-		self.log_window(new_index)
-		
-	def log_window(self, index):
-		if self._window != None:
-			PM.log(str(index + 1) + '/' + str(len(self._windows)) + ': ' + self._window.get_parameter().get_id(), 0)
-		
-	def log(self, message, mid):
-		ticks = pygame.time.get_ticks()
-		if mid == 0:
-			self._log_msg_id = (self._log_msg_id % 1000) + 1
-			mid = self._log_msg_id
-		
-		found = False
-		for log_entry in self._log_queue:
-			if log_entry[0] == mid:
-				log_entry[1] = message
-				found = True
-				log_entry[2] = ticks
-
-		self.purge_logs()
-		
-		# remove old messages if necessary
-		if not found:
-			if len(self._log_queue) >= self._log_lines :
-				self.purge_oldest_log()
-			self._log_queue.append([mid, message, ticks])
-			
-		self.render()
-		
-		return mid
-	
-	def close(self):
-		pygame.display.quit()
+		"""
+        pygame.init()
+        pygame.mouse.set_visible(False)
+
+        # seems to suit RPi
+        self._color_depth = 16
+
+        # pygame.display.set_mode((0, 0), pygame.FULLSCREEN, self._color_depth)
+        pygame.display.set_mode((640, 480), 0, self._color_depth)
+        self._surface = pygame.display.get_surface()
+
+        self._clock = pygame.time.Clock()
+
+        self._width = self._surface.get_width()
+        self._height = self._surface.get_height()
+
+        self._subwindow_alpha = 200
+
+        self._font_size = int(self._height / 14)
+        self._font = pygame.font.SysFont(pygame.font.get_default_font(), self._font_size)
+        self._font_aa = 0
+        self._fg_color = pygame.Color(255, 191, 0)
+        self._bg_color = pygame.Color(0, 0, 0)
+        self._dim_color = pygame.Color(200, 140, 0)
+
+        self._log_lines = 4
+        self._log_msg_id = 0
+        self._log_surface = pygame.Surface((self._width / 2, self._font_size * self._log_lines), 0, self._color_depth)
+        self._log_surface.set_alpha(self._subwindow_alpha)
+        self._log_queue = []
+
+        logger = PM()
+        logger.set(self.log)
+
+        self._fps_log_id = 0
+        self._frame_no = 0
+        self.load_resources()
+        pygame.time.set_timer(PMScreen.LOG_FPS_EVENT, 10000)
+        pygame.time.set_timer(PMScreen.LOG_STATS_EVENT, 30000)
+        pygame.time.set_timer(PMScreen.ONE_SEC_EVENT, 1000)
+
+        self._window = None
+        self._windows = []
+
+        self._pos_log_id = 0
+        self._mouse_down_pos = (0, 0)
+        self._mouse_down_mark_timeout = 0
+
+    def clear(self):
+        self._surface.fill(self._bg_color)
+
+    def load_resources(self):
+        self._bg_img = pygame.image.load(os.path.join('res', 'subaru_logo.png')).convert()
+        self._bg_img_rect = self._bg_img.get_rect()
+
+    def render(self):
+        self._clock.tick()
+
+        for event in pygame.event.get():
+            if event.type == PMScreen.LOG_FPS_EVENT:
+                self._frame_no += 1
+                self._fps_log_id = PM.log("FPS %.2f" % self._clock.get_fps(), self._fps_log_id)
+
+            elif event.type == PMScreen.LOG_STATS_EVENT:
+                if platform.system() == "Linux":
+                    PMUtils.log_os_stats()
+            elif event.type == pygame.QUIT:
+                self.close()
+                sys.exit()
+
+            elif event.type == pygame.MOUSEBUTTONUP:
+                self._mouse_down_mark_timeout = 0
+                self._mouse_down_pos = pygame.mouse.get_pos()
+                self._pos_log_id = PM.log('Mouse up at: %s/%s' % pygame.mouse.get_pos(), self._pos_log_id)
+                if self._mouse_down_pos[0] < self._width / 2:
+                    self.prev_window()
+                else:
+                    self.next_window()
+            elif event.type == pygame.K_LEFT:
+                self.prev_window()
+            elif event.type == pygame.K_RIGHT:
+                self.next_window()
+            elif event.type == PMScreen.ONE_SEC_EVENT:
+                self._mouse_down_mark_timeout += 1
+
+        self.clear()
+
+        if self._window is None:
+            self.render_bg()
+
+        if self._window is not None:
+            self._window.render()
+
+        self.render_log()
+
+        if self._mouse_down_mark_timeout < 2:
+            pygame.draw.circle(self._surface, self._dim_color, self._mouse_down_pos, 16)
+
+        pygame.display.update()
+
+    def render_log(self):
+        self.purge_logs()
+        if len(self._log_queue) == 0:
+            return
+
+        self._log_surface.fill(self._bg_color)
+
+        log_pos = 0
+        for msg_entry in self._log_queue:
+            msg_entry[2] += 1
+            message = msg_entry[1]
+            message_lbl = self._font.render(message, self._font_aa, self._fg_color, self._bg_color)
+            self._log_surface.blit(message_lbl, (0, log_pos))
+            log_pos += self._font_size
+
+        self._surface.blit(self._log_surface, (0, self._height - self._log_surface.get_height()))
+
+    def render_bg(self):
+        # self._surface.blit(self._bg_img, self._bg_img_rect)
+        pass
+
+    def purge_oldest_log(self):
+        to_be_deleted = None
+        oldest = pygame.time.get_ticks()
+
+        for log_entry in self._log_queue:
+            if log_entry[2] < oldest:
+                oldest = log_entry[2]
+                to_be_deleted = log_entry
+
+        if to_be_deleted is not None:
+            self._log_queue.remove(to_be_deleted)
+
+
+    def purge_logs(self):
+        to_be_deleted = []
+
+        for log_entry in self._log_queue:
+            if pygame.time.get_ticks() - log_entry[2] > 5000:
+                to_be_deleted.append(log_entry)
+
+        for log_entry in to_be_deleted:
+            self._log_queue.remove(log_entry)
+
+    def add_window(self, window):
+        self._windows.append(window)
+
+    def set_window(self, window):
+        if self._window is not None:
+            self._window.set_surface(None)
+
+        self._window = window
+        self._window.set_surface(self._surface)
+
+    def get_window(self):
+        return self._window
+
+    def next_window(self):
+        if not self._windows:
+            return
+
+        if self._window is not None:
+            index = self._windows.index(self._window)
+        else:
+            index = -1
+
+        new_index = (index + 1) % len(self._windows)
+        self.set_window(self._windows[new_index])
+        self.log_window(new_index)
+
+    def prev_window(self):
+        if not self._windows:
+            return
+
+        if self._window is not None:
+            index = self._windows.index(self._window)
+        else:
+            index = 1
+
+        new_index = (index - 1) % len(self._windows)
+        self.set_window(self._windows[new_index])
+        self.log_window(new_index)
+
+    def log_window(self, index):
+        if self._window is not None:
+            PM.log(str(index + 1) + '/' + str(len(self._windows)) + ': ' + self._window.get_parameter().get_id(), 0)
+
+    def log(self, message, mid):
+        ticks = pygame.time.get_ticks()
+        if mid == 0:
+            self._log_msg_id = (self._log_msg_id % 1000) + 1
+            mid = self._log_msg_id
+
+        found = False
+        for log_entry in self._log_queue:
+            if log_entry[0] == mid:
+                log_entry[1] = message
+                found = True
+                log_entry[2] = ticks
+
+        self.purge_logs()
+
+        # remove old messages if necessary
+        if not found:
+            if len(self._log_queue) >= self._log_lines:
+                self.purge_oldest_log()
+            self._log_queue.append([mid, message, ticks])
+
+        self.render()
+
+        return mid
+
+    def close(self):
+        pygame.display.quit()

+ 60 - 62
pimonitor/ui/PMSingleWindow.py

@@ -1,69 +1,67 @@
-'''
+"""
 Created on 22-04-2013
 
 @author: citan
-'''
+"""
 
 import pygame
 
+
 class PMSingleWindow(object):
-	'''
-	classdocs
-	'''
-	
-	def __init__(self, param):
-		self._fg_color = pygame.Color(230, 166, 0)
-		self._fg_color_dim = pygame.Color(200, 140, 0)
-		self._bg_color = pygame.Color(0, 0, 0)
-		self._param = param
-		self._packets = None
-		
-		self._x_offset = 0
-		
-	def set_surface(self, surface):
-		if surface == None:
-			return
-
-		self._surface = surface
-		self._width = self._surface.get_width();
-		self._height = self._surface.get_height();
-
-		self._title_font_size = int(self._surface.get_height() / 12)
-		self._value_font_size = int(self._surface.get_height() / 1.8)
-		self._unit_font_size = int(self._surface.get_height() / 4)
-		
-		self._title_font = pygame.font.SysFont(pygame.font.get_default_font(), self._title_font_size)
-		self._value_font = pygame.font.SysFont(pygame.font.get_default_font(), self._value_font_size)
-		self._unit_font = pygame.font.SysFont(pygame.font.get_default_font(), self._unit_font_size)
-		
-		self._font_aa = 1
-
-		self._title_lbl = self._title_font.render(self._param.get_name(), self._font_aa, self._fg_color)
-				
-		self._unit_lbl = self._unit_font.render(self._param.get_default_unit(), self._font_aa, self._fg_color_dim)
-		self._end_x_offset = self._width - self._unit_lbl.get_width() - 10 
-	
-	def render(self):
-		if self._packets != None:
-			if self._param.get_address_length() > 0:
-				value = self._param.get_value(self._packets[0])
-			elif self._param.get_dependencies():
-				value = self._param.get_calculated_value(self._packets)
-		else:
-			value = "??"
-		
-		value_lbl_width = self._value_font.render(value, self._font_aa, self._fg_color).get_width()
-		self._x_offset = (self._width - value_lbl_width) / 2		
-		value_lbl = self._value_font.render(value, self._font_aa, self._fg_color)
-		
-		self._surface.blit(self._title_lbl, (2, 2))
-		self._surface.blit(value_lbl, (self._x_offset, 10 + self._title_font_size))
-		self._surface.blit(self._unit_lbl, (self._end_x_offset, 10 + self._title_font_size + self._value_font_size))
-		
-	def set_packets(self, packets):
-		self._packets = packets
-		
-	def get_parameter(self):
-		return self._param
-		
-		
+    """
+    classdocs
+    """
+
+    def __init__(self, param):
+        self._fg_color = pygame.Color(230, 166, 0)
+        self._fg_color_dim = pygame.Color(200, 140, 0)
+        self._bg_color = pygame.Color(0, 0, 0)
+        self._param = param
+        self._packets = None
+
+        self._x_offset = 0
+
+    def set_surface(self, surface):
+        if surface is None:
+            return
+
+        self._surface = surface
+        self._width = self._surface.get_width()
+        self._height = self._surface.get_height()
+
+        self._title_font_size = int(self._surface.get_height() / 12)
+        self._value_font_size = int(self._surface.get_height() / 1.8)
+        self._unit_font_size = int(self._surface.get_height() / 4)
+
+        self._title_font = pygame.font.SysFont(pygame.font.get_default_font(), self._title_font_size)
+        self._value_font = pygame.font.SysFont(pygame.font.get_default_font(), self._value_font_size)
+        self._unit_font = pygame.font.SysFont(pygame.font.get_default_font(), self._unit_font_size)
+
+        self._font_aa = 1
+
+        self._title_lbl = self._title_font.render(self._param.get_name(), self._font_aa, self._fg_color)
+
+        self._unit_lbl = self._unit_font.render(self._param.get_default_unit(), self._font_aa, self._fg_color_dim)
+        self._end_x_offset = self._width - self._unit_lbl.get_width() - 10
+
+    def render(self):
+        value = "??"
+        if self._packets is not None:
+            if self._param.get_address_length() > 0:
+                value = self._param.get_value(self._packets[0])
+            elif self._param.get_dependencies():
+                value = self._param.get_calculated_value(self._packets)
+
+        value_lbl_width = self._value_font.render(value, self._font_aa, self._fg_color).get_width()
+        self._x_offset = (self._width - value_lbl_width) / 2
+        value_lbl = self._value_font.render(value, self._font_aa, self._fg_color)
+
+        self._surface.blit(self._title_lbl, (2, 2))
+        self._surface.blit(value_lbl, (self._x_offset, 10 + self._title_font_size))
+        self._surface.blit(self._unit_lbl, (self._end_x_offset, 10 + self._title_font_size + self._value_font_size))
+
+    def set_packets(self, packets):
+        self._packets = packets
+
+    def get_parameter(self):
+        return self._param

+ 74 - 75
pimonitor/ui/PMWindow.py

@@ -1,83 +1,82 @@
-'''
+"""
 Created on 22-04-2013
 
 @author: citan
-'''
+"""
 
 import pygame
 
+
 class PMWindow(object):
-	'''
+    """
 	classdocs
-	'''
-	
-	def __init__(self):
-		self._fg_color = pygame.Color(255, 255, 255)
-		self._bg_color = pygame.Color(0, 0, 0)
-		self._dict = dict()
-		
-		# P60 Gear position
-		# P97 Transfer Duty Ratio
-		# P96 Lock Up Duty Ratio
-		# P122 Oil Temperature
-		# P104 ATF Temperature
-		self._pids = ["P60", "P97", "P96", "P122", "P104"]
-		
-	def set_surface(self, surface):
-		self._surface = surface
-		self._width = self._surface.get_width();
-		self._height = self._surface.get_height();
-
-		self._title_font_size = int(self._surface.get_height() / 16)
-		self._value_font_size = int(self._surface.get_height() / 3)
-		self._title_font = pygame.font.SysFont(pygame.font.get_default_font(), self._title_font_size)
-		self._value_font = pygame.font.SysFont(pygame.font.get_default_font(), self._value_font_size)
-
-		self._font_aa = 1
-		
-		self._value_lbl_width = self._value_font.render("999", self._font_aa, self._fg_color).get_width()
-		
-	
-	def render(self):
-		
-		first_row_height = self._title_font_size + self._value_font_size + 10
-		second_row_height = first_row_height + self._title_font_size + self._value_font_size + 20
-		pygame.draw.line(self._surface, self._fg_color, (0, first_row_height + 10), (self._width, first_row_height + 10))
-
-		for param, value in self._dict.iteritems():
-			title = param.get_name() #+ " (" + param.get_default_unit() + ")"
-			
-			
-			first_row_ids = ["P60", "P122", "P104"]
-			if param.get_id() in first_row_ids:
-				index = first_row_ids.index(param.get_id())
-				x_offset = (self._width / len(first_row_ids)) * index + 10
-				
-				titlelbl = self._title_font.render(title, self._font_aa, self._fg_color)
-				valuelbl = self._value_font.render(value, self._font_aa, self._fg_color)
-				self._surface.blit(titlelbl, (x_offset + 10, 10))
-				self._surface.blit(valuelbl, (x_offset + 10, 10 + self._title_font_size))
-
-				pygame.draw.line(self._surface, self._fg_color, (x_offset, 0), (x_offset, first_row_height))
-			
-			second_row_ids = ["P97", "P96"]
-			
-			if param.get_id() in second_row_ids:
-				index = second_row_ids.index(param.get_id())
-				x_offset = (self._width / len(second_row_ids)) * index + 10
-
-				titlelbl = self._title_font.render(title, self._font_aa, self._fg_color)
-				valuelbl = self._value_font.render(value, self._font_aa, self._fg_color)
-				self._surface.blit(titlelbl, (x_offset + 10, first_row_height + 20))
-				self._surface.blit(valuelbl, (x_offset + 10, first_row_height + 20 + self._title_font_size))
-				
-				pygame.draw.line(self._surface, self._fg_color, (x_offset, first_row_height + 20), (x_offset, second_row_height))
-			
-				x_offset += 10
-
-	def get_pids(self):
-		return self._pids 
-	
-	def set_value(self, param, packet):
-		self._dict[param] = param.get_value(packet)
-		
+	"""
+
+    def __init__(self):
+        self._fg_color = pygame.Color(255, 255, 255)
+        self._bg_color = pygame.Color(0, 0, 0)
+        self._dict = dict()
+
+        # P60 Gear position
+        # P97 Transfer Duty Ratio
+        # P96 Lock Up Duty Ratio
+        # P122 Oil Temperature
+        # P104 ATF Temperature
+        self._pids = ["P60", "P97", "P96", "P122", "P104"]
+
+    def set_surface(self, surface):
+        self._surface = surface
+        self._width = self._surface.get_width()
+        self._height = self._surface.get_height()
+
+        self._title_font_size = int(self._surface.get_height() / 16)
+        self._value_font_size = int(self._surface.get_height() / 3)
+        self._title_font = pygame.font.SysFont(pygame.font.get_default_font(), self._title_font_size)
+        self._value_font = pygame.font.SysFont(pygame.font.get_default_font(), self._value_font_size)
+
+        self._font_aa = 1
+
+        self._value_lbl_width = self._value_font.render("999", self._font_aa, self._fg_color).get_width()
+
+
+    def render(self):
+
+        first_row_height = self._title_font_size + self._value_font_size + 10
+        second_row_height = first_row_height + self._title_font_size + self._value_font_size + 20
+        pygame.draw.line(self._surface, self._fg_color, (0, first_row_height + 10),
+                         (self._width, first_row_height + 10))
+
+        for param, value in self._dict.iteritems():
+            title = param.get_name()  # + " (" + param.get_default_unit() + ")"
+
+            first_row_ids = ["P60", "P122", "P104"]
+            if param.get_id() in first_row_ids:
+                index = first_row_ids.index(param.get_id())
+                x_offset = (self._width / len(first_row_ids)) * index + 10
+
+                titlelbl = self._title_font.render(title, self._font_aa, self._fg_color)
+                valuelbl = self._value_font.render(value, self._font_aa, self._fg_color)
+                self._surface.blit(titlelbl, (x_offset + 10, 10))
+                self._surface.blit(valuelbl, (x_offset + 10, 10 + self._title_font_size))
+
+                pygame.draw.line(self._surface, self._fg_color, (x_offset, 0), (x_offset, first_row_height))
+
+            second_row_ids = ["P97", "P96"]
+
+            if param.get_id() in second_row_ids:
+                index = second_row_ids.index(param.get_id())
+                x_offset = (self._width / len(second_row_ids)) * index + 10
+
+                titlelbl = self._title_font.render(title, self._font_aa, self._fg_color)
+                valuelbl = self._value_font.render(value, self._font_aa, self._fg_color)
+                self._surface.blit(titlelbl, (x_offset + 10, first_row_height + 20))
+                self._surface.blit(valuelbl, (x_offset + 10, first_row_height + 20 + self._title_font_size))
+
+                pygame.draw.line(self._surface, self._fg_color, (x_offset, first_row_height + 20),
+                                 (x_offset, second_row_height))
+
+    def get_pids(self):
+        return self._pids
+
+    def set_value(self, param, packet):
+        self._dict[param] = param.get_value(packet)

+ 1 - 1
run.sh

@@ -1,2 +1,2 @@
 #!/bin/bash
-sudo PYTHONPATH=. python /home/pi/devel/PiMonitor/pimonitor/PMMain.py
+sudo PYTHONPATH=. python2.7 /Users/citan/devel/workspace/PiMonitor/pimonitor/PMMain.py