VMware Monitoring on Apple/Android Smart Watch

 VMware Monitoring on Apple/Android Smart Watch


Why

A few years ago, I was very active in the Android Watch Community including designing custom watch faces with programmatic actions. I eventually moved back to actual watches where I did not have to worry about battery life. Recently, I have been pining for a watch that can be viewed in any light, so I dug out my old Samsung smart watch and placed it back in action.

Not knowing if it could be possible, I thought "I wonder if I could send vCenter metrics to my watch and graph them?" I knew this would require digging into the vCenter REST API and Powershell - both of which I do not use very often. Well, somehow, I figured out enough for an automated Proof of Concept. I use the term Proof of Concept as I know there are more elegant ways to do what I did, but these instructions should be enough for someone else to build something fabulous.

How

Parts List

Extract Metrics from vCenter

I started playing with the vCenter REST APIs in Postman to see if I could come up with a way to pull CPU & RAM utilization for ESXi hosts. There weren't great examples and the API documentation in vCenter did not present me with an obvious solution. Since the best vCenter scripting seems to be done in PowerCLI, I looked around for a PowerCLI example I could modify. I found a great one from a previous Nutanix employee here (The blog is actually named VirtualDennis. How perfect.) I modified VirtualDennis' PowerCLI script and came up with this simple script:

# Main Variables (Edit As Needed)
#
# Enter the IP Address of your vCenter Server
$vcenter = "192.168.1.55"
# Enter the Domain Login information for your vCenter Server
$vcuser = "administrator@vsphere.local"# Enter the password for the user above
$vcpwd = "SuperSecretPassword"

# Connect to VC
#Run this once# Set-PowerCLIConfiguration -InvalidCertificateAction:Ignore
Connect-VIServer $vcenter -User $vcuser -Password $vcpwd -ea silentlycontinue -WarningAction 0
#Connect-VIServer $vcenter -User $vcuser -Password $vcpwd
#$vmhost = Get-VMHost
#$vmhost | Get-Stat -Stat cpu.usagemhz.average -Realtime -MaxSamples 1
Get-VMHost | select Name, ConnectionState, PowerState, @{Name = 'CpuUsage'; Expression = {($_.CpuUsageMhz / $_.CpuTotalMhz).ToString("P")}}, @{Name = 'MemoryUsage'; Expression = {($_.MemoryUsageGB / $_.MemoryTotalGB).ToString("P")}}, Version | Export-Csv "/var/www/html/dmf-info.csv"

#Disconnect from current vCenter
Disconnect-VIServer $vcenter -Confirm:$false

(Edit the script to reflect the IP address of your vCenter server, your vCenter username, your vCenter password, and where the resulting CSV file should be located)

The CSV file created by this script will look something like this:

"Name","ConnectionState","PowerState","CpuUsage","MemoryUsage","Version"
"nuc.fios-router.home","Connected","PoweredOn","16.42 %","50.24 %","7.0.1"
"rpi4.fios-router.home","Connected","PoweredOn","5.24 %","68.81 %","7.0.0"

Install PowerShell

Of course, we need the PowerShell interpreter to run this script. If you are running on Windows, PowerShell is already installed. I decided to use a Raspberry Pi OS VM on a Raspberry Pi 4 ESXi host, so I needed to install Linux PowerShell. Below are the instructions for installing PowerShell on Raspberry Pi OS. You can find other instructions here.

sudo apt-get install libunwind8

wget https://github.com/PowerShell/PowerShell/releases/download/v7.1.2/powershell-7.1.2-linux-arm32.tar.gz

mkdir ~/powershell

tar -xvf ./powershell-7.1.2-linux-arm32.tar.gz -C ~/powershell

sudo ln -s ~/powershell/pwsh /usr/bin/pwsh
sudo ln -s ~/powershell/pwsh /usr/local/bin/powershell

Note: I noticed that Raspberry Pi PowerShell expects to run on an actual Raspberry Pi and looks for specific hardware that does not exist in a VM. To fix this, just include "export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1" in any shell script.

Install PowerCLI

The PowerCLI PowerShell module allows you to do cool VMware stuff with PowerShell and is easy to install.  After starting the PowerShell interpreter (pwsh on Linux), just type this command:

Install-Module VMware.PowerCLI -Scope CurrentUser.

 The VMware guide to PowerCLI installation can be found here.

Install a Simple Web Server to Host Your CSV for Your Phone to Grab

You may already have a web server running on your PowerShell host. If not, install one. I find the darkhttpd web server quick and easy. On my Raspberry Pi OS VM, I added these lines to the /etc/rc.local file to start the darkhttpd server on boot:

#DMF Start Simple Web Server
#/home/pi/darkhttpd/darkhttpd /var/www/html --port 7777 > /dev/null 2>&1 &

Pull VMware Metrics at Regular Intervals

Now that you have a PowerShell script that pulls metrics and places them on a web server. You want to have this done automatically at regular intervals. I created a simple shell script and then placed that script in cron. Here is the shell script, get-esxi-stats.sh:

#!/bin/bash
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
/usr/bin/pwsh /home/pi/get-esxi-stats.ps1  

Here is the crontab entry that runs every five minutes:

# Pull ESXi Stats for Android Tasker for Android Watchmaker
*/5 * * * * /bin/bash /home/pi/get-esxi-stats.sh > /dev/null 2>&1



Create a Tasker Task to Pull VMware Metrics and Send to Watch

OK. Now we are going to do some fun phone/watch stuff. We'll start with Android Tasker. (I do not own an Apple watch, so I do not know if there is an equivalent app for Apple watches that can pull data and send to the WatchMaker app.) I learned how to parse CSV files in Tasker by watching this excellent video.

First, I created a Tasker task, named Watchmaker Vars, that pulls the CSV file from my web server, assigns values to variables and sends those variables to the WatchMaker app. (If you have any trouble with this, feel free to DM me on Twitter @DennisFaucher. I have also included the actual Tasker XML that you can import to Tasker in the Appendix below.)



Next, I created a Tasker profile, named Watchmaker 2 Min, that runs the Watchmaker Vars task every two minutes. I have included the Tasker XML for this profile in the Appendix as well. The Profile XML also includes the Task XML.



Create a Watch Face That Uses the Tasker Variables

We have some VMware variables sent to the Watchmaker App. Let's create a watch face to use them and graph them. As a Proof of Concept, I created a super simple watch face with digital time and four Ring Layers - one for each variable. You can import my watch face from the GetWatchmaker web site here.

That's it. Cron will run the shell script, that runs the PowerShell script that dumps the CSV on the web server. Tasker will pull the CSV from the web server every 2 minutes and send new variables to the watch face. Magic.

Thank you

Thank you for taking the time to read this post. This Proof of Concept was fun to build and drew on some of my favorite topics - Custom smart watch faces, and VMware. I welcome your feedback.

Appendix

Tasker Task XML


<TaskerData sr="" dvi="1" tv="5.12.22">
<Task sr="task20">
<cdate>1628253620226</cdate>
<edate>1628455571040</edate>
<id>20</id>
<nme>Watchmaker Vars</nme>
<pri>6</pri>
<Action sr="act0" ve="7">
<code>339</code>
<Bundle sr="arg0">
<Vals sr="val">
<net.dinglisch.android.tasker.RELEVANT_VARIABLES>&lt;StringArray sr=""&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;%http_cookies
Cookies
The cookies the server sent in the response in the Cookie:COOKIE_VALUE format. You can use this directly in the 'Headers' field of the HTTP Request action&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;%http_file_output
File Output
Will always contain the file's full path even if you specified a directory as the File to save.&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;%http_response_code
Response Code
The HTTP Code the server responded&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;%http_headers()
Response Headers
The HTTP Headers the server sent in the response. Each header is in the 'key:value' format&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;%http_response_length
Response Length
The size of the response in bytes&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;&lt;/StringArray&gt;</net.dinglisch.android.tasker.RELEVANT_VARIABLES>
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
</Vals>
</Bundle>
<Int sr="arg1" val="0"/>
<Int sr="arg10" val="0"/>
<Int sr="arg11" val="0"/>
<Int sr="arg12" val="1"/>
<Str sr="arg2" ve="3">http://faucher.no-ip.org:7777/dmf-info.csv</Str>
<Str sr="arg3" ve="3"/>
<Str sr="arg4" ve="3"/>
<Str sr="arg5" ve="3"/>
<Str sr="arg6" ve="3"/>
<Str sr="arg7" ve="3">Download/dmf-info.csv</Str>
<Int sr="arg8" val="30"/>
<Int sr="arg9" val="0"/>
</Action>
<Action sr="act1" ve="7">
<code>417</code>
<Str sr="arg0" ve="3">Download/dmf-info.csv</Str>
<Str sr="arg1" ve="3">%csv</Str>
<Int sr="arg2" val="1"/>
</Action>
<Action sr="act2" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%RPI4CPU</Str>
<Str sr="arg1" ve="3">%csv[4](2)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act3" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%RPI4CPU</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%RPI4CPU</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%RPI4CPU</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act4" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%RPI4RAM</Str>
<Str sr="arg1" ve="3">%csv[5](2)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act5" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%RPI4RAM</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%RPI4RAM</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%RPI4RAM</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act6" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%NUCCPU</Str>
<Str sr="arg1" ve="3">%csv[4](3)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act7" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%NUCCPU</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%NUCCPU</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%NUCCPU</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act8" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%NUCRAM</Str>
<Str sr="arg1" ve="3">%csv[5](3)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act9" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%NUCRAM</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%NUCRAM</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%NUCRAM</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
</Task>
</TaskerData>

Tasker Profile XML


<TaskerData sr="" dvi="1" tv="5.12.22">
<Profile sr="prof19" ve="2">
<cdate>1628253553333</cdate>
<edate>1628455860014</edate>
<flags>8</flags>
<id>19</id>
<mid0>20</mid0>
<nme>Watchmaker 2 Min</nme>
<Time sr="con0">
<fh>5</fh>
<fm>0</fm>
<rep>2</rep>
<repval>2</repval>
<th>22</th>
<tm>0</tm>
</Time>
</Profile>
<Task sr="task20">
<cdate>1628253620226</cdate>
<edate>1628455571040</edate>
<id>20</id>
<nme>Watchmaker Vars</nme>
<pri>6</pri>
<Action sr="act0" ve="7">
<code>339</code>
<Bundle sr="arg0">
<Vals sr="val">
<net.dinglisch.android.tasker.RELEVANT_VARIABLES>&lt;StringArray sr=""&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;%http_cookies
Cookies
The cookies the server sent in the response in the Cookie:COOKIE_VALUE format. You can use this directly in the 'Headers' field of the HTTP Request action&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;%http_file_output
File Output
Will always contain the file's full path even if you specified a directory as the File to save.&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;%http_response_code
Response Code
The HTTP Code the server responded&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;%http_headers()
Response Headers
The HTTP Headers the server sent in the response. Each header is in the 'key:value' format&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3&gt;&lt;_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;%http_response_length
Response Length
The size of the response in bytes&lt;/_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4&gt;&lt;/StringArray&gt;</net.dinglisch.android.tasker.RELEVANT_VARIABLES>
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
</Vals>
</Bundle>
<Int sr="arg1" val="0"/>
<Int sr="arg10" val="0"/>
<Int sr="arg11" val="0"/>
<Int sr="arg12" val="1"/>
<Str sr="arg2" ve="3">http://faucher.no-ip.org:7777/dmf-info.csv</Str>
<Str sr="arg3" ve="3"/>
<Str sr="arg4" ve="3"/>
<Str sr="arg5" ve="3"/>
<Str sr="arg6" ve="3"/>
<Str sr="arg7" ve="3">Download/dmf-info.csv</Str>
<Int sr="arg8" val="30"/>
<Int sr="arg9" val="0"/>
</Action>
<Action sr="act1" ve="7">
<code>417</code>
<Str sr="arg0" ve="3">Download/dmf-info.csv</Str>
<Str sr="arg1" ve="3">%csv</Str>
<Int sr="arg2" val="1"/>
</Action>
<Action sr="act2" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%RPI4CPU</Str>
<Str sr="arg1" ve="3">%csv[4](2)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act3" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%RPI4CPU</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%RPI4CPU</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%RPI4CPU</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act4" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%RPI4RAM</Str>
<Str sr="arg1" ve="3">%csv[5](2)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act5" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%RPI4RAM</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%RPI4RAM</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%RPI4RAM</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act6" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%NUCCPU</Str>
<Str sr="arg1" ve="3">%csv[4](3)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act7" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%NUCCPU</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%NUCCPU</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%NUCCPU</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
<Action sr="act8" ve="7">
<code>547</code>
<Str sr="arg0" ve="3">%NUCRAM</Str>
<Str sr="arg1" ve="3">%csv[5](3)</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
<Int sr="arg5" val="3"/>
<Int sr="arg6" val="1"/>
</Action>
<Action sr="act9" ve="7">
<code>690818506</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.twofortyfouram.locale.intent.extra.BLURB>%NUCRAM</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>tasker_var</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS>
<net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>java.lang.String</net.dinglisch.android.tasker.extras.VARIABLE_REPLACE_KEYS-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
<tasker_var>%NUCRAM</tasker_var>
<tasker_var-type>java.lang.String</tasker_var-type>
<tasker_var_name>%NUCRAM</tasker_var_name>
<tasker_var_name-type>java.lang.String</tasker_var_name-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">slide.watchFrenzy</Str>
<Str sr="arg2" ve="3">slide.watchFrenzy.TaskerSendVariableActivity</Str>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
</Action>
</Task>
</TaskerData>

Comments

Michael White said…
This comment has been removed by a blog administrator.
Michael White said…
Can you show us the watch face with the vC Info?
Dennis Faucher said…
You can show any information you want. Just change the PowerShell.