(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 VariablesCultureInfo 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 Addressif ( 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 DataConsole.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 DataConsole.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 Datareturn 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 Messageif ( 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 TextConsole.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 Textreturn -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 keyreturn 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: 2025-10-11; loaded in 0.0109 seconds