Kevin’s Week 1 Report:
This week and a little over break I worked on setting up program that can take in data and store it in a database. I am using WAMPServer and C# in Visual Studio to do this. This program will have an interface to the user that is used for initially setting up the system. The user can enter their information in the boxes in the display and click “Start Logging Data” to begin storing power data usage. The boxes will be for naming the sensors and providing addresses for where data is coming from for those sensors.
The code below is used to start logging data into a database whenever the start button is pushed. The data used is a random value generated from 30-50(for Sensor 1) and 20-40(for Sensor 2); this is for testing purposes only. Every second, data for these sensors is passed into the database. Every 60 seconds the past 60 entries are averaged to give the minute data. The same general procedure will be used for the hour, day, month, etc. data. Program seems to be working well so far, I just need to test for longer time periods to see if data remains accurate.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Net;
using System.Threading;
namespace SensorTool
{
public partial class Form1 : Form
{
public ListBox debug;
public string connectionStr;
public List<Thread> threadPool;
public delegate void DebugCallback(string message);
public Form1()
{
InitializeComponent();
}
private void butLogger_Click(object sender, EventArgs e)
{
if (butLogger.Text.Contains("Start"))
{
debug = lbDebug;
threadPool = new List<Thread>();
connectionStr = "server=" + txtDBServer.Text
+ "; Port=" + txtPort.Text
+ "; user id=" + txtUsername.Text
+ "; password=" + txtPassword.Text
+ "; database=" + txtDBName.Text;
if (senName1.Text != "" && senAdd1.Text != "")
createThread(senName1.Text, senAdd1.Text);
if (senName2.Text != "" && senAdd2.Text != "")
createThread(senName2.Text, senAdd2.Text);
if (senName3.Text != "" && senAdd3.Text != "")
createThread(senName3.Text, senAdd3.Text);
if (senName4.Text != "" && senAdd4.Text != "")
createThread(senName4.Text, senAdd4.Text);
if (senName5.Text != "" && senAdd5.Text != "")
createThread(senName5.Text, senAdd5.Text);
if (senName6.Text != "" && senAdd6.Text != "")
createThread(senName6.Text, senAdd6.Text);
setAll(false);
butLogger.Text = "Stop Logging Data";
}
else
{
foreach (Thread threadKill in threadPool)
{
threadKill.Abort();
}
setAll(true);
butLogger.Text = "Start Logging Data";
}
}
private void createThread( string sensorName, string sensorAddress)
{
SensorThread st = new SensorThread(sensorName, sensorAddress, connectionStr, this);
Thread thr = new Thread(st.startThread);
thr.IsBackground = true;
thr.Start();
threadPool.Add(thr);
UpdateDebugOutput("Added thread for: " + sensorName);
}
public void UpdateDebugOutput(string message)
{
debug.Items.Add(DateTime.Now.ToString() + " - " + message);
debug.SelectedIndex = debug.Items.Count - 1;
debug.SelectedIndex = -1;
}
private void setAll(bool active)
{
txtDBServer.Enabled = active;
txtDBName.Enabled = active;
txtUsername.Enabled = active;
txtPassword.Enabled = active;
txtPort.Enabled = active;
senName1.Enabled = active;
senAdd1.Enabled = active;
senName2.Enabled = active;
senAdd2.Enabled = active;
senName3.Enabled = active;
senAdd3.Enabled = active;
senName4.Enabled = active;
senAdd4.Enabled = active;
senName5.Enabled = active;
senAdd5.Enabled = active;
senName6.Enabled = active;
senAdd6.Enabled = active;
}
private void butDebug_Click(object sender, EventArgs e)
{
txtDBServer.Text = "localhost";
txtDBName.Text = "powertracker";
txtUsername.Text = "root";
txtPassword.Text = "";
txtPort.Text = "3306";
senName1.Text = "Sensor1";
senAdd1.Text = "http://localhost/dummydata1.php";
senName2.Text = "Sensor2";
senAdd2.Text = "http://localhost/dummydata2.php";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;
using System.Net;
namespace SensorTool
{
class SensorThread
{
private string name;
private string address;
private string connStr;
private Form1 form;
public SensorThread(string sensorName, string sensorAddress, string connection,
Form1 userForm)
{
name = sensorName;
address = sensorAddress;
form = userForm;
connStr = connection;
}
public void startThread()
{
MySqlConnection dbCon = new MySqlConnection(connStr);
int counter = 0;
while (true)
{
//Read Sensor
String sensorValue = "";
try
{
WebClient client = new WebClient();
sensorValue = client.DownloadString(address);
}
catch (Exception)
{
string error = "Unable to read " + name;
form.debug.BeginInvoke(
new Form1.DebugCallback(form.UpdateDebugOutput), error);
}
//Write to Database
try
{
DBnonQuery("INSERT INTO DataTemp VALUES (NOW(), '"
+ name + "', " + sensorValue + ")");
}
catch (Exception)
{
string error = "Unable to write " + name + "'s value to database";
form.debug.BeginInvoke(
new Form1.DebugCallback(form.UpdateDebugOutput), error);
}
counter++;
if (counter == 60)
{
averageSeconds();
clearSeconds();
counter = 0;
}
Thread.Sleep(1000);
}
}
private void averageSeconds()
{
//time will be the middle of the past 60 measurements
DateTime prevMinuteTime = DateTime.Now.AddSeconds(-30);
MySqlConnection dbCon = new MySqlConnection(connStr);
dbCon.Open();
string query = "SELECT SensorVal FROM DataTemp WHERE SensorID='" + name + "' LIMIT 0,60";
MySqlCommand dbCmd = new MySqlCommand(query, dbCon);
MySqlDataReader dbDr = dbCmd.ExecuteReader();
int total = 0;
while (dbDr.Read())
{
total += Int32.Parse(dbDr.GetString(0));
}
dbCon.Close();
int count = 60;
string prevTimeStr = prevMinuteTime.ToString("yyyy-MM-dd HH:mm:00");
DBnonQuery("INSERT INTO DataMinute VALUES( '" + prevTimeStr
+ "', '" + name + "', " + (total / count) + ")");
string msg = " Count: " + count.ToString() + " Total: "
+ total.ToString() + " Average: " + (total / count).ToString();
form.debug.BeginInvoke(
new Form1.DebugCallback(form.UpdateDebugOutput), msg);
}
private void clearSeconds()
{
DBnonQuery("DELETE FROM DataTemp WHERE SensorID='" + name + "'");
string msg = "Cleaned DATATEMP of " + name;
form.debug.BeginInvoke(
new Form1.DebugCallback(form.UpdateDebugOutput), msg);
}
private void DBnonQuery(string query)
{
MySqlConnection dbCon = new MySqlConnection(connStr);
dbCon.Open();
MySqlCommand dbCmd = new MySqlCommand(query, dbCon);
dbCmd.ExecuteReader();
dbCon.Close();
}
}
}