Battery Level using System Management in C# - c#

So I'm working on a speech recognition program in C# and I'v compiled a few lines of code that speaks back the current battery level when I say "battery Level". Only problem is, It doesn't work.
Debugging stage it builds fine, no errors or warnings yet when I say "battery level" I get no response.
if (e.Result.Text == "battery level")
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
String estimatedChargeRemaining = String.Empty;
foreach (var battery in allBatteries)
{
estimatedChargeRemaining = Convert.ToString(battery["EstimatedChargeRemaining"]);
}
JARVIS.Speak("Estimated Charge Remaining: " + estimatedChargeRemaining + "%");
return;
}
Does anyone notice any obvious mistakes in the code that could prevent it from working?
Thanks.

There are couple of mistakes in your code that may or may not be affecting your application
if (e.Result.Text.ToLower() == "battery level") //First Change
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
String estimatedChargeRemaining = String.Empty;
foreach (var battery in allBatteries)
{
estimatedChargeRemaining = Convert.ToString(battery["EstimatedChargeRemaining"]);
JARVIS.Speak("Estimated Charge Remaining: " + estimatedChargeRemaining + "%"); //second change as you may have more than one batteries.
}
return;
}

Related

Reading and processing command output line by line in SSH.NET

I am working on a home project that needs to execute some commands via SSH, read back the responses and display them on a web page. A lot of the time it does work, but now and then i get some inconsistent behavior, for example certain lines of output are missed that would instruct on what to do next, this results in a hung session, and a requirement to restore IIS.
I have included the code below, like I said I am not a full time developer, so its gonna be a mess, but hopefully someone can point me in the right direction to understand what i got so wrong, and what i need to change, i wont learn if you just past code snippets up, id much rather attempt to try and fix what i have.
using (SshClient ssh = new SshClient("192.168.0.119", "x", "x."))
{
ssh.Connect();
ShellStream shell = ssh.CreateShellStream("Tail", 0, 0, 0, 0, 1024);
StreamWriter wr = new StreamWriter(shell);
StreamReader rd = new StreamReader(shell);
wr.AutoFlush = true;
if (extract)
{
Console.WriteLine("Downloading DataZIP");
ssh.RunCommand("wget " + zipURL);
}
bool reading = shell.CanRead;
wr.WriteLine("cd " + remoteFilePath + packagename + " && docker build -t dockerfile .");
while (reading)
{
Clients.Caller.builderOut(shell.ReadLine().ToString());
if (shell.ReadLine().ToString().Contains("Successfully"))
{
Clients.Caller.builderOut("Build Complete");
reading = false;
}
if (shell.ReadLine().ToString().Contains("returned a non-zero code: "))
{
goto end;
}
}
if (data.Type == TemplateType.Data)
{
wr.WriteLine("cd " + remoteFilePath + packagename + " && docker tag dockerfile " + data.Repository + "/" + data.packagename.ToLower() + ":data.Type");
wr.WriteLine("cd " + remoteFilePath + packagename + " && docker push " + data.Repository + "/" + data.packagename.ToLower() + ":data.Type");
}
reading = shell.CanRead;
while (reading)
{
Clients.Caller.builderOut("Pushing this will take a moment");
if (shell.ReadLine().ToString().Contains("digest:"))
{
Clients.Caller.builderOut("Pushed");
reading = false;
}
}
Clients.Caller.builderOut("End");
ssh.Disconnect();
ssh.Dispose();
}
What I think I got wrong
I think I get these errors due to the way I'm reading the console output. I think that that data changes so fast we miss some:
while (reading)
{
Clients.Caller.builderOut(shell.ReadLine().ToString());
if (shell.ReadLine().ToString().Contains("Successfully"))
{
Clients.Caller.builderOut("Build Complete");
reading = false;
}
if (shell.ReadLine().ToString().Contains("returned a non-zero code: "))
{
goto end;
}
}
So using that each of the 3 checks on the output could I think be be missing some of the lines, as the output is quite speedy, while its reading the value changes so the next check has different init data to check, and thus we skip over what would otherwise be the exit lines or next job lines.
You have to store the line that you read into a variable and do the checks against the stored value:
while (reading)
{
string line = shell.ReadLine();
Clients.Caller.builderOut(line);
if (line.Contains("Successfully"))
{
Clients.Caller.builderOut("Build Complete");
reading = false;
}
if (line.Contains("returned a non-zero code: "))
{
goto end;
}
}

Battery Status in winforms

I have been creating a winform application using perfmon. I have found out that the battery status will not work because its part of windows management. So I decide to go the wmi route.
So my question is when I put the battery status in a label as shown below:
private void BatteryStatus()
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
foreach (var battery in allBatteries)
{
int estimatedChargeRemaining = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
if (estimatedChargeRemaining == 100)
{
label13.Text = "Remaining:" + " " + estimatedChargeRemaining + " " + "%";
}
}
}
The charge remaining is shown perfectly. My question is, is there a way that I can have just one if statement to call the battery status from 100 to 1
or the way I am doing it will I have to do 99 more if statements?
this is part of my performance monitor I am custom building. It would be easier if perfmon would allow the counter. This is the only way I can think of to get the battery stats such as:
Charge Rate
Discharge Rate
Remaining Capacity
Voltage
I have always did if statements with the labels on battery status. Before I go into doing 99 more if statements I want to be sure there is not an easier way?
*********** Update ************
I figured it out. Thanks for the help for the ones who helped.
I thing that what you want to do is this:
private void BatteryStatus()
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
foreach (var battery in allBatteries)
{
int estimatedChargeRemaining = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
label13.Text = "Remaining:" + " " + estimatedChargeRemaining + " " + "%";
}
}
No need for and if statment, the label will be updated no matter what the percentage is.
On the second part of the question you say that you want to show the "battery status", you can then use if like this:
private void BatteryStatus()
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
foreach (var battery in allBatteries)
{
int estimatedChargeRemaining = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
string Status = "";
if(estimatedChargeRemaining < 15) Status = "Critical";
else if(estimatedChargeRemaining < 35) Status = "Low";
else if(estimatedChargeRemaining < 60) Status = "Regular";
else if(estimatedChargeRemaining < 90) Status = "High";
else Status = "Complete";
label13.Text = "Remaining:" + " " + estimatedChargeRemaining + " " + "% | Status: " + Status;
}
}
private void BatteryStatus()
{
System.Management.ManagementClass wmi = new System.Management.ManagementClass("Win32_Battery");
var allBatteries = wmi.GetInstances();
foreach (var battery in allBatteries)
{
int estimatedChargeRemaining = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
label13.Text = "Remaining" + " " + estimatedChargeRemaining.ToString() + " " + "%";
if (estimatedChargeRemaining < 15 )
{
label13.ForeColor = Color.Red;
}
}
}

Can Anyone help me retrieve data from parse using unity please?

I have managed to store data, but I can't retrieve it and i would be so grateful if someone could just help me get at least 1 example working.
First I am storing data when the user signs up:
public void SetupNewParseMember(ParseUser user)
{
ParseObject gameScore = new ParseObject("GameScore");
gameScore["cash"] = 500;
gameScore["playerName"] = user.Username;
gameScore["HighestCash"] = 500;
gameScore["GamesPlayed"] = 0;
Task saveTask = gameScore.SaveAsync();
}
This works fine, I can see the data in parse and all seems ok..
The problem is when i try to retrieve the objects.
public void SetupMainScreen(ParseUser user)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username);
query.FindAsync().ContinueWith(t =>
{
IEnumerable<ParseObject> results = t.Result;
List<ParseObject> resultsList = results.ToList();
DealWithResults(resultsList, user);
});
}
public void DealWithResults(List<ParseObject> resultsList, ParseUser me)
{
userGamesPlayed = resultsList[1].Get<int>("GamesPlayed");
userHighestCash = resultsList[2].Get<int>("HighestCash");
userCash = resultsList[3].Get<int>("Cash");
WelcomeText.text = "Welcome, " + me.Username + "\n" +
"Cash: $" + userCash + "\n" +
"Highest Cash: $" + userHighestCash + "\n" +
"Games Played: " + userGamesPlayed;
}
First I tried just making changes to the unity ui from inside the Query but that did not work, So i made an outside function and passed the results to it that way, and that still does not work?
I tried to debug what i was getting in the list with this:
foreach (var res in resultsList)
{
Debug.Log("Class Name = " + res.ClassName + "| Keys are: " + res.Keys);
}
But all it returned was:
Class Name = GameScore| Keys are: System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]
Can anyone offer any insights?
EDIT2:
ok so first i found results list and its contents
http://i.imgur.com/IKcBbey.png
Then if i open it, it seems to be null ref?
http://i.imgur.com/VmSpi9c.png
But if i go digging, i found the info i need all the way down here
http://i.imgur.com/1Wwu5uc.png
Now just need to work out how to get it?
As there is only one set of data it is always accessible through resultsList[0]. What you want is:
double cash = (double)resultsList[0]["cash"];
string playerName = (string)resultsList[0]["playerName"];
double highestCash = (double)resultsList[0]["HighestCash"];
int gamesPlayed = (int)resultsList[0]["GamesPlayed"];
Though you probably want to check that resultsList is not null and contains one element before you try to dereference it.
Also as your ParseObject appears to be a Dictionary you might find this MSDN page useful.
Ended up solving it.. Much different to the examples...
I had to make a coroutine that called a function on callback to access the variables outside of the query.
I called it with
StartCoroutine(SetupMainScreen(me, DealWithResults));
then called this.
public IEnumerator SetupMainScreen(ParseUser user, Action<GameScore> callback)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username).FirstOrDefaultAsync();
while (!query.IsCompleted)
{
yield return null;
}
if (query.IsFaulted || query.IsCanceled)
{
Debug.Log("Getting of GameScores faulted or cancelled...");
}
else
{
var obj = query.Result;
if (obj != null)
callback(new GameScore(obj.Get<int>("cash"),obj.Get<string>("playerName"),obj.Get<int>("HighestCash"),obj.Get<int>("GamesPlayed")));
}
}
public void DealWithResults(GameScore gs)
{
WelcomeText.text = "Welcome, " + gs.Username + "\n" +
"Cash: $" + gs.Cash + "\n" +
"Highest Cash: $" + gs.HighestCash + "\n" +
"Games Played: " + gs.GamesPlayed;
}
And i just made a class to hold the objects.. Hopefully this helps someone else.

Using the Splunk SDK for C#, why is oneshot search ignoring the set time range?

I have an odd problem with setting time range for oneshot search. I set time range for my oneshot search, but results are just first found on server matching query. It seems like oneshot is just ignoring time range.
I've read:
How to run searches and jobs using the Splunk SDK for C# -
http://dev.splunk.com/view/csharp-sdk/SP-CAAAEQG
Service.SearchOneShotAsync Method -
http://docs.splunk.com/DocumentationStatic/CshrpSDK/2.1.1/Splunk.Client/html/a5323948-7506-ad15-6f04-7a95b70e616d.htm
JobArgs Class -
http://docs.splunk.com/DocumentationStatic/CshrpSDK/2.1.1/Splunk.Client/html/7dc4e71d-1ed7-4eb1-5a10-183d7663da26.htm
Time modifiers for search -
http://docs.splunk.com/Documentation/Splunk/6.0.3/SearchReference/SearchTimeModifiers
but after hours of tests and experiments - nothing.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var connectArgs = new ServiceArgs
{
Host = "myip",
Port = 8089,
Scheme = "https"
};
Splunk.Service service = new Splunk.Service(connectArgs);
service.Login("login", "password");
var oneshotSearchArgs = new Splunk.Client.JobArgs();
oneshotSearchArgs.EarliestTime = "2015-08-23 13:00";//textBoxOD.Text + "T" + textBoxODG.Text + ":00.000";
oneshotSearchArgs.LatestTime = "2015-08-23 14:00";//textBoxDO.Text + "T" + textBoxDOG.Text + ":00.000";
String oneshotSearchQuery = "search query *" + textBox1.text + "* | head 500";
var outArgs = new JobResultsArgs
{
OutputMode = JobResultsArgs.OutputModeEnum.Xml,
Count = 0,
};
try
{
using (var stream = service.Oneshot(oneshotSearchQuery, outArgs))
{
using (var rr = new ResultsReaderXml(stream))
{
string raw = "_raw";
foreach (var #event in rr)
{
wynik += "EVENT:" + Environment.NewLine;
foreach (string key in #event.Keys)
{
if (key.Contains(raw))
{
wynik += " " + key + " -> " + #event[key] + Environment.NewLine + Environment.NewLine;
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Sorry for being so late with an answer. I landed into the same issue.
The reason that your OneShot search ignores the time range is because it does not take one. (I did not come across any documentation to do so)
To overcome this issue, I tried the 2.X SDK for C#. It fixed the issue.
You can use the 2.X version in 3 steps:
Setting up Service parameters. (host, port etc.)
Authenticating the Service.
Setting up parameters for the OneShot job and executing it.
You can find the NuGet package "Splunk PCL Client for .Net" in NuGet library here.
Here is a sample code:
// Setting up Service parameters
Service _splunkService = new Service(Scheme.Https, "your-api-or-ip", 8089);
// Authenticating
await _splunkService.LogOnAsync("username", "password");
// Setting up parameters for the OneShot job and executing it
var query = "your search query";
var oneShot = new JobArgs();
oneShot.EarliestTime = DateTime.Now.AddMinutes(-2).Date.ToString("yyyy-MM-dd") + "T" + DateTime.Now.AddMinutes(-2).TimeOfDay; //"2015-09-12T12:00:00.000-07:00";
oneShot.LatestTime = "your latest time";
using (var stream = await _splunkService.SearchOneShotAsync(query, 0, oneShot))
{
try
{
foreach (var result in stream)
{
var rawValue = Convert.ToString(result.GetValue("_raw"));
if (rawValue != null)
{
// do something.
}
}
}
}
Make sure the 'await' parts go inside an async method.

Outlook 2003 - Recurring items showing the first occurrences start/end date

Background: I'm writing an application in C# (.NET 3.5), that looks at multiple users Outlook 2003 calendars (using COM objects), gets the appointments and inserts the data for those appointments into a database.
Problem: After the first users calendar, any recurring items on the following calendars, will always have a start and end time of the first occurrence of that item. I'm releasing the COM Objects between users (and during, if the user has a lot of items), and The item collection is being restricted correctly (due to there only being a handful of the recurring tasks inserted (albeit the wrong start/end) instead of infinite from the "no end" tasks). The correct start/end time is part of the requirements, having the information available for this or another application to work out how much free time a user has for a given range of dates, and working hours.
Code: (Variable declarations omitted, they're at the top of the relevant functions)
Looping through the users (in Main()):
foreach (DataRow drUserCalendar in dtCalendars.Rows)
{
//for each calendar we're looking at, export their calendar data and put it in the database
try
{
appOutlook = new Outlook.Application();
ExportCalendar(drUserCalendar);
Marshal.FinalReleaseComObject(appOutlook);
GC.Collect();
}
catch (Exception ex)
{
//report error
}
}
Extracting information from the calendar
static void ExportCalendar(DataRow drUser)
{
strDisplayName = drUser["DisplayName"].ToString();
strUserID = drUser["ID"].ToString();
int.TryParse(drUser["PreviousDays"].ToString(), out intPrevious);
int.TryParse(drUser["FutureDays"].ToString(), out intFuture);
dtmAllowedPreviousStart = DateTime.Now.AddDays(-intPrevious);
dtmAllowedFutureStart = DateTime.Now.AddDays(intFuture);
nsOne = appOutlook.GetNamespace("MAPI");
nsOne.Logon(null, null, false, false);
rcpOne = nsOne.CreateRecipient(strDisplayName);
intCount = 0;
if (rcpOne.Resolve())
{
fldOne = nsOne.GetSharedDefaultFolder(rcpOne, Outlook.OlDefaultFolders.olFolderCalendar);
strRestrict = "[Start] > '" + MIN_START_DATE.ToString("g") + "' And [End] < '" + MAX_START_DATE.ToString("g") + "'";
itms = fldOne.Items;
itms.Sort("[Start]", Type.Missing);
itms.IncludeRecurrences = true;
itmsRestricted = itms.Restrict(strRestrict);
itmsRestricted.Sort("[Start]", Type.Missing);
itmsRestricted.IncludeRecurrences = true;
blnIsRecurring = false;
dicRecurringTaskTracker = new Dictionary<string, int>();
foreach (object objOne in itmsRestricted)
{
if (intCount >= 100 || blnIsRecurring)
{
//release COM objects. Outlook doesn't like you having more than 250 ish items without cleaning up.
Marshal.FinalReleaseComObject(appOutlook);
appOutlook = new Outlook.Application();
GC.Collect();
intCount = 0;
}
if (objOne is Outlook.AppointmentItem)
{
appItem = (Outlook.AppointmentItem)objOne;
blnException = false;
//get data from the item
strEntryID = appItem.EntryID;
strSubject = appItem.Subject;
strBody = appItem.Body;
dtmStart = appItem.Start;
dtmEnd = appItem.End;
blnException = EXCEPTIONS.Contains(strSubject);
//if the item is an exception we're done with it.
if (!blnException)
{
strRecurrenceInterval = "";
strRecurrenceType = "";
strRecurrenceInfo = "";
//check if it's a recurring task.
blnIsRecurring = appItem.IsRecurring;
if (blnIsRecurring)
{
//check to see if we've already had a task from this series
if (!dicRecurringTaskTracker.Keys.Contains(strEntryID))
{
//Start at 0 so the first (this) task
//is number 1.
dicRecurringTaskTracker.Add(strEntryID, 0);
}
//update number
dicRecurringTaskTracker[strEntryID] += 1;
//change the subject to add the count on the end
strEntryID = strEntryID + '-' + dicRecurringTaskTracker[strEntryID].ToString();
//it's a recurring task, so we need to find out when/how often.
rpTaskRecurrence = appItem.GetRecurrencePattern();
rtTaskRecurrenceType = rpTaskRecurrence.RecurrenceType;
strRecurrenceType = rtTaskRecurrenceType.ToString();
strRecurrenceInterval = rpTaskRecurrence.Interval.ToString();
switch (strRecurrenceType)
{
case "olRecursDaily":
case "olRecursMonthNth":
case "olRecursWeekly":
strRecurrenceInfo = rpTaskRecurrence.DayOfWeekMask.ToString();
break;
case "olRecursMonthly":
strRecurrenceInfo = rpTaskRecurrence.DayOfMonth.ToString();
break;
}
}
if (strEntryID != null && strSubject != null && dtmStart != null && dtmEnd != null
&& (intPrevious == 0 || (dtmStart > dtmAllowedPreviousStart)) && (intFuture == 0 || (dtmStart < dtmAllowedFutureStart)))
{
//build up the SQL
strSQL = "EXEC UpdateCalendarEntry ";
strSQL += "#EntryID='" + strEntryID + "', ";
strSQL += "#Subject='" + strSubject.Replace("'", "''") + "', ";
strSQL += "#Body='" + strSubject.Replace("'", "''") + "', ";
strSQL += "#StartDate='" + dtmStart.ToString("dd-MMM-yyyy HH:mm:ss") + "', ";
strSQL += "#EndDate='" + dtmEnd.ToString("dd-MMM-yyyy HH:mm:ss") + "', ";
strSQL += "#UserCalendarID=" + strUserID + ",";
strSQL += "#Recurring = " + blnIsRecurring.ToString() + ",";
strSQL += "#RecurrenceType = '" + strRecurrenceType + "',";
strSQL += "#RecurrenceInterval = '" + strRecurrenceInterval + "',";
strSQL += "#RecurrenceInfo = '" + strRecurrenceInfo + "';";
try
{
//Execute SQL
}
catch (Exception ex)
{
//Print error message
MessageBox.Show(ex.ToString());
}
}
}
Marshal.FinalReleaseComObject(appItem);
GC.Collect();
}
strEntryID = null;
strSubject = null;
strBody = null;
intCount++;
}
//finished looping, do some clean up.
Marshal.FinalReleaseComObject(nsOne);
Marshal.FinalReleaseComObject(rcpOne);
Marshal.FinalReleaseComObject(fldOne);
Marshal.FinalReleaseComObject(itms);
Marshal.FinalReleaseComObject(itmsRestricted);
GC.Collect();
}
else
{
throw new Exception("Could not resolve name");
}
}
I can't see an obvious problem with your code I'm afraid but as I expect your well aware there is probably some other stuff happening behind the scenes that is causing your problem.
I have covered some things I found to be best practice when I was working with this stuff in a blog article - http://jynxeddevelopment.blogspot.com. It might be worth a read to see if anything seems different to what you are doing, I think the section 'Keep references to everything' might be useful.
I'm not sure your COM objects will be collected with the GC call as you're not setting them to null first, however either way this shouldn't make a difference. I got this sort of thing working without any GC calls.
Things to look at:
objOne should be release EVERY loop if it's a COM object (I expect it is)
Closing your Outlook application before releasing it (appOutlook.Close()), I'm surprised your not getting lots of them hanging around
Examine every field you are using on the COM object, if they are COM objects too they might need Finalising too
Sorry this is nothing concrete but working with this stuff is hard work :/ Good luck!
-Jynx
After testing I've found that the issue relates to my (or whoever runs the application) permissions on the users (shared) calendar(s) that are being looked at.
It works on the first user because that's myself in this case. It doesn't work on users after that because i don't have sufficient rights it seems (confirmed by having my colleague changing it so default users are "owners" on his calendar and running the application again, and it working for his calendar).
I have since tried to use GetOccurrence(DateTime) (surrounded with a while loop), however that lead to the same issue. The function would error when there was no occurrence (as expected), but when it found an occurrence it would return a null object.
However because I wasn't using the object for anything other than getting the start and end date of the task, I worked it out manually (I had the original task, meaning i could get the duration, by incrementing each day until I get an occurrence I'd get the reccurring tasks start date, and using the duration of the task I calculated the end date).
It's not an ideal solution, but if you're just wanting to get recurring tasks it's simple enough to do (though resource consuming if you have a lot of reccurring tasks and are looping for a long period of time)

Categories

Resources