(view source code of youless.cs as plain text)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
namespace RobvanderWoude
{
internal class Youless
{
static readonly string progver = "1.00";
static string address = "youless";
static string ipaddress = string.Empty;
static int Main( string[] args )
{
#region Initialize Variables
CultureInfo culture = CultureInfo.GetCultureInfo( "en-US" );
CultureInfo.CurrentCulture = culture; // SETTING CurrentCulture requires .NET Framework 4.6
string exepath = new Uri( Assembly.GetExecutingAssembly( ).CodeBase ).LocalPath;
string configfile = Path.Combine( Directory.GetParent( exepath ).FullName, Path.GetFileNameWithoutExtension( exepath ) + ".ip" );
#endregion Initialize Variables
#region Get Youless Address
if ( args.Contains( "/?" ) )
{
return ShowHelp( );
}
else if ( args.Length == 0 )
{
// Get the IP address for the default hostname "youless"
ValidateAddress( address );
}
else if ( args.Length == 1 )
{
if ( ValidateAddress( args[0] ) )
{
address = args[0];
}
}
else if ( args.Length > 1 )
{
return ShowHelp( );
}
else if ( File.Exists( configfile ) )
{
address = File.ReadAllText( configfile ).Trim( );
if ( !ValidateAddress( address ) )
{
File.Delete( configfile );
address = string.Empty;
}
}
if ( string.IsNullOrWhiteSpace( ipaddress ) )
{
while ( string.IsNullOrWhiteSpace( ipaddress ) )
{
address = PromptForIP( );
}
}
if ( !File.Exists( configfile ) )
{
File.WriteAllText( configfile, ipaddress );
}
#endregion Get Youless Address
#region Device Data
Console.WriteLine( );
string url = string.Format( "http://{0}/d", ipaddress );
YoulessClass.fw = string.Empty;
if ( !YoulessReadData( url ) )
{
Console.Error.WriteLine( "\nUitlezen Youless {0} niet gelukt", ipaddress );
return -1;
}
Console.WriteLine( "Youless model :\t{0}", YoulessClass.model );
if ( !string.IsNullOrWhiteSpace( YoulessClass.fw ) )
{
Console.WriteLine( "Youless firmware :\t{0}", YoulessClass.fw );
}
Console.WriteLine( "Youless MAC adres :\t{0}", YoulessClass.mac );
Console.WriteLine( "Youless IP adres :\t{0}", ipaddress );
#endregion Device Data
#region Power Consumption Data
Console.WriteLine( );
url = string.Format( "http://{0}/e", ipaddress ); // URL for power consumption log
if ( YoulessReadData( url ) )
{
Console.WriteLine( "Tijdstip :\t{0}", YoulessClass.gts.ToString( "yyyy-MM-dd HH:mm" ) );
Console.WriteLine( );
Console.WriteLine( "Vermogen :\t{0} W", YoulessClass.pwr );
Console.WriteLine( "P1 afname hoog tarief :\t{0} kWh", YoulessClass.p1 );
Console.WriteLine( "P1 afname laag tarief :\t{0} kWh", YoulessClass.p2 );
Console.WriteLine( "P1 teruglevering hoog tarief :\t{0} kWh", YoulessClass.n1 );
Console.WriteLine( "P1 teruglevering laag tarief :\t{0} kWh", YoulessClass.n2 );
Console.WriteLine( "Netto totaal verbruik :\t{0} kWh", YoulessClass.net );
Console.WriteLine( );
Console.WriteLine( "Gas verbruik :\t{0} m\x00B3", YoulessClass.gas );
}
else
{
Console.Error.WriteLine( "\nUitlezen Youless {0} niet gelukt", ipaddress );
return -1;
}
#endregion Power Consumption Data
return 0;
}
static PingReply Ping( string address )
{
Ping pingSender = new Ping( );
PingOptions options = new PingOptions( );
options.DontFragment = true;
// Create a buffer of 32 bytes of data to be transmitted.
string data = new string( 'a', 32 );
byte[] buffer = Encoding.ASCII.GetBytes( data );
int timeout = 120;
return pingSender.Send( address, timeout, buffer, options );
}
static string PromptForIP( )
{
Console.Write( "Vul het IP-adres van de Youless in: " );
string ip = Console.ReadLine( ).Trim( );
if ( ValidateAddress( ip, true ) )
{
return ip;
}
else
{
return string.Empty;
}
}
public static int ShowHelp( params string[] errmsg )
{
#region Error Message
if ( errmsg.Length > 0 )
{
List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
}
#endregion Error Message
#region Help Text
/*
Youless.exe, Version 1.00
Read data from a Youless LS120 energy monitor device
Usage: Youless.exe [ ip ]
Where: ip is the IP address of the Youless device
Notes: If no IP address is specified, the program will try to resolve the
IP address for hostname "youless". If unsuccessful, you will be
prompted to enter it, and the address will be saved in a file
named Youless.cfg in the program's parent directory.
This program requires .NET Framework version 4.6.
Return code (\"ErrorLevel\") equals -1 in case of (command line)
errors, otherwise 0.
Written by Rob van der Woude
https://www.robvanderwoude.com
*/
#endregion Help Text
#region Display Help Text
Console.Error.WriteLine( );
Console.Error.WriteLine( "Youless.exe, Version {0}", progver );
Console.Error.WriteLine( "Read data from a Youless LS120 energy monitor device" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "Youless.exe [ ip ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "ip" );
Console.ResetColor( );
Console.Error.WriteLine( " is the IP address of the Youless device" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Notes: If no IP address is specified, the program will try to resolve the" );
Console.Error.WriteLine( " IP address for hostname \"youless\". If unsuccessful, you will be" );
Console.Error.WriteLine( " prompted to enter it, and the address will be saved in a file" );
Console.Error.WriteLine( " named Youless.ip in the program's parent directory." );
Console.Error.WriteLine( " This program requires .NET Framework version 4.6." );
Console.Error.WriteLine( " Return code (\"ErrorLevel\") equals -1 in case of (command line)" );
Console.Error.WriteLine( " errors, otherwise 0." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Text
return -1;
}
static bool ValidateAddress( string address, bool iponly = false )
{
bool valid = true;
if ( iponly )
{
Regex regex = new Regex( @"^(\d+(\.\d+){3}|[:a-f\d]{3,})$", RegexOptions.IgnoreCase );
valid = regex.IsMatch( address );
}
if ( valid )
{
PingReply reply = Ping( address );
valid = ( reply.Status == IPStatus.Success );
if ( valid )
{
ipaddress = reply.Address.ToString( );
}
else
{
Console.Error.WriteLine( "Unable to reach {0}", address );
}
}
return valid;
}
static bool YoulessReadData( string url )
{
try
{
using ( WebClient wc = new WebClient( ) )
{
string[] json = wc.DownloadString( url ).Split( "{}[],".ToCharArray( ), StringSplitOptions.RemoveEmptyEntries );
foreach ( string keyval in json )
{
string key = keyval.Split( ":".ToCharArray( ) )[0].Trim( "\"\t ".ToCharArray( ) );
string val = keyval.Split( ":".ToCharArray( ), 2 )[1].Trim( "\"\t ".ToCharArray( ) );
switch ( key )
{
case "cs0":
YoulessClass.cs0 = double.Parse( val );
break;
case "fw":
YoulessClass.fw = val;
break;
case "gas":
YoulessClass.gas = double.Parse( val );
break;
case "gts":
string timestamp = string.Format( "20{0}-{1}-{2} {3}:{4}", val.Substring( 0, 2 ), val.Substring( 2, 2 ), val.Substring( 4, 2 ), val.Substring( 6, 2 ), val.Substring( 8, 2 ) );
YoulessClass.gts = DateTime.Parse( timestamp );
break;
case "mac":
YoulessClass.mac = val.Replace( ':', '-' ).ToUpper( );
break;
case "model":
YoulessClass.model = val;
break;
case "n1":
YoulessClass.n1 = double.Parse( val );
break;
case "n2":
YoulessClass.n2 = double.Parse( val );
break;
case "net":
YoulessClass.net = double.Parse( val );
break;
case "p1":
YoulessClass.p1 = double.Parse( val );
break;
case "p2":
YoulessClass.p2 = double.Parse( val );
break;
case "ps0":
YoulessClass.ps0 = int.Parse( val );
break;
case "pwr":
YoulessClass.pwr = int.Parse( val );
break;
case "tm":
YoulessClass.tm = new DateTime( long.Parse( val ) );
break;
case "ts0":
YoulessClass.ts0 = new DateTime( long.Parse( val ) );
break;
default:
// invalid/unknown key
return false;
}
}
}
return true;
}
catch ( Exception e )
{
Console.Error.WriteLine( e.Message );
return false;
}
}
}
public static class YoulessClass
{
public static double cs0
{
get; set;
}
public static string fw
{
get; set;
}
public static double gas
{
get; set;
}
public static DateTime gts
{
get; set;
}
public static string mac
{
get; set;
}
public static string model
{
get; set;
}
public static double n1
{
get; set;
}
public static double n2
{
get; set;
}
public static double net
{
get; set;
}
public static double p1
{
get; set;
}
public static double p2
{
get; set;
}
public static int ps0
{
get; set;
}
public static int pwr
{
get; set;
}
public static DateTime tm
{
get; set;
}
public static DateTime ts0
{
get; set;
}
}
}
page last modified: 2024-04-16; loaded in 0.0084 seconds