Alexa, turn off the TV

I’ve been playing with home automation for about a year or two and am pretty happy with my setup. I mostly use Z-Wave devices (a proprietary wireless mesh network) with Vera Lite hub that can be accessed via HTTP (web pages, smartphone apps, etc). I plan to write more about it another time, but since I haven’t updated my blog for 4 years I need to start with something smaller and simpler.

Amazon Echo

I discovered Amazon Echo (a.k.a. “Alexa”) when it was in beta and I immediately preordered one. It really is the missing link in the evolution of smart home, and vice versa – home automation is Echo’s “killer app”. It doesn’t seem as much, but it’s a very good quality bluetooth speaker, fused with the best voice recognition technology I’ve ever used. The voice recognition happens in the cloud (amazon’s servers) and it can be used to check weather, set alarms and timers, check spelling, wikipedia etc. Coming from Europe, I use it often to convert the local units to the standard ones (Alexa, what’s 100 degrees Fahrenheit in Celcius… Alexa, convert 130 pounds to kilos.. ). In any case, I love this device. Despite my Polish accent, it can understand me very well. And unlike most phones or even wearables, I don’t have to “trigger” it with any button – I can yell “alexa” from a ladder, with hands covered in paint, and ask her to turn on more lights – been there, done that – it beats operating a smart phone app for sure.

Again, I plan to write a detailed post of my configuration but today let’s just say that I can use Alexa to send a HTTP GET request to any HTTP endpoint and trigger some actions. While my Z-Wave switches can control many devices, they are not the best candidate for controlling my TV screen – if I use a switch to cut off the TV’s power, I won’t be able to turn it back on using the standard TV remote (and vice versa).

Arduino IR blaster to the rescue!

I needed a way to send a TV remote signal (on/off) using IR (infrared) LED. I played with Arduino before and I knew it was pretty easy, but also I remembered that using an IR library was taking most of the available storage space on Arduino (I use Diecimila with 14KB of available storage) and I could no longer use Ethernet library when I used IR. So this time I ended up controlling the Arduino via USB cable, using an always-on HTPC (home theather PC, or as I call it – “the laptop behind the TV”). Since my setup also involves a Raspberry Pi with Linux, I could probably control the IR LED with that, but in my case that was not convenient (my PC is next to the TV, whereas the RPI is far away and hidden).

First, you need an IR LED 940nm – $1.50, https://www.sparkfun.com/products/9349
and Arduino (I used Diecimila, I think the current UNO model is the most similar) – make sure you can connect it to PC without extra converters – $25, https://www.sparkfun.com/products/11021

Ideally, you should also add a 100 Ohm resistor – I had these 330 Ohm resistors laying around so I used 3 of them in parallel to get ~110 Ohm. I am not expert (far from it) but I was told the LED should use a 100 Ohm resistor, even though you don’t really need it for the short bursts used for IR remote.

arduino-led-3
Note: the LED orientation is important. Pay close attention to the metal elements visible inside the LED, or the length of the legs. Short bursts from arduino should not burn the LED and you should see the light using a digital camera (if you don’t, switch the LED orientation and re-test briefly). Your eyes can’t see IR, but most digital cameras capture it as purple light, just look at the camera’s preview. Check out my clip attached to this post, you should see the faint light.

The IR sample code I found used pin 3 so I also used that one, but any PWM pin will do, and you may find one closer to GND for easier assembly. Just make sure you update the Arduino sketch.

#include <IRremote.h>
IRsend irsend;

//samsung tv power on/off
unsigned int S_pwr[68]={4600,4350,700,1550,650,1550,650,1600,650,450,650,450,650,450,650,450,700,400,700,1550,650,1550,650,1600,650,450,650,450,650,450,700,450,650,450,650,450,650,1550,700,450,650,450,650,450,650,450,650,450,700,400,650,1600,650,450,650,1550,650,1600,650,1550,650,1550,700,1550,650,1550,650};

void setup()
{
    Serial.begin(9600);
}

void loop() {
    if (Serial.read() != -1) {
        irsend.sendRaw(S_pwr,68,38);
    }
}

(copy at https://gist.github.com/Ekus/92842e60e8a3f53f38d3 )

the Samsung On/Off code (for S_pwr variable) I googled on github. The arduino IRRemote library contains codes for some other brands built in. If you don’t find your code, you can always “record it” with an IR photoresistor attached to Arduino, but that’s another project.

After assembly, my Arduino looked like this:

WP_20160112_009

I wrapped the LED cable around the Arduino to avoid disconnecting the pins when moving the cable, and wrapped everything in some antistatic foil I had lying around. I also added some hook & loop (a.k.a. velcro) sticker to attach the LED to the furniture and keep it pointed in the general direction of my TV.

WP_20160112_002

Once I had my Arduino ready and working, I had to control it from my PC.

I’m using Windows 10 so I went to the control panel to “install Windows components” and installed IIS with ASP.NET. I then made this ASP.NET file and put it in the root folder, or in a new application folder:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@Import Namespace="System.IO.Ports" %>

<script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
          using (SerialPort sp = new System.IO.Ports.SerialPort()) 
          { 
            sp.PortName = "COM3";
            sp.BaudRate = 9600;
            sp.Open();
            sp.Write("1"); 
            System.Threading.Thread.Sleep(100);
            sp.Write("1"); // repeat, just in case. That's not the best way to do it but I didn't have time to investigate Samsung IR codes more. It's good enough.
            sp.Close();
          }
        }
</script>

<html>
  <body>
    <h1>HI</h1>
    <%=System.DateTime.Now %>
  </body>
</html>

(copy at https://gist.github.com/Ekus/4f86aba04487bdb452a4 )

Now, whenever I (or my Alexa->home automation bridge) open the page http://<ip of my htpc>/EkusTV.aspx, the page executes and causes the arduino to send the on/off signal. In my next blog post I plan to describe this missing link – how I got my Amazon Echo to send the http request to my devices. In the meantime, enjoy the clip below!

2016-01-13 at 3:09

Started playing with IfThisThenThat.

Started playing with IfThisThenThat. It's automagic.

I'm trying to have all my g+ posts captured and republished to my proper blog (it's a safe archive, as no one reads it except for occasional google spider).

Also, another copy should be made to my Dropbox (we'll see if it saves pictures). Or my gmail. The combinations are endless.

Scott Hanselman originally shared this post:

Essential IFTTT (IfThisThenThat) – Programming Workflows for Humans using the Web's Social Glue – Scott Hanselman

from Andrzej Rusztowicz – Google+ User Feed https://plus.google.com/116749729898732576109/posts/iuec8b8c7VX

2011-09-14 at 18:51

Simple web proxy in ASP.NET

In last two weeks, on two separate occasions, I needed a simple web service that would act as proxy to remote servers.

First, while writing my crude twitter ticker in Silverlight, I run into issue with lack of support for GIF images in Silverlight, and potentially also with accessing 3rd party servers. Normally, Silverlight and Flash (and also JavaScript) are able to freely contact ONLY their server of origin, but due to XSS attacks accessing other hosts is… less than ideal.

In this case I set up a simple ASP.NET handler that receives requests from my Silverlight program using URL like this:
http://localhost/imageproxy.ashx?url=http://remote.server.com/some/alien/avatar.gif

then the service contacts the URL specified in parameter, downloads the data and returns it to the original Silverlight app, in single trip. In my case the service also re-encodes the images as JPEG’s or PNG’s which are easier to work with in SL, but that step is optional, as most of the pictures are JPEG’s anyway and are passed through without changes. I used code from the article Silverlight: Handling Cross-Domain Images and Gifs by and modified it slightly.

A week later I was forced to overhear my unholy fallen .netless colleagues talking repeatedly about problems with accessing MS Reporting Services from Hell Java and blaming Integrated Windows Authentication (a.k.a. NTLM). When they started considering setting up ISA Server (aptly renamed to Microsoft Forefront Threat Management Gateway), I offered a single-file alternative that I could write in 5 minutes. Java would call this unsecured proxy, which in turn would apply security and access the MS Reporting server.

Two hours later the file was mostly done, tested and somewhat working. In order to host it under IIS on Windows you need to put it some existing “web folder”, e.g. c:\Inetpub\wwwroot\ or create separate one using IIS manager. No manual compilation is needed, just make sure the server has ASP.NET installed and enabled (tested on version 4.0 and IIS 7.5).

The usage is similar to the previous example, but it adds hard-coded credentials and POST support, used for talking to SOAP web services.

Please see the whole file below, including a funny fake password. Some cleaning and tuning advised, regarding error handling and security. I’m posting it anyway, even though one could probably write it from scratch faster than read this lengthy blog post.

The file should be saved with .ashx extension. Use at your own risk.

<%@ WebHandler Language="C#" Class="Ekus.WebServiceProxy" %>
using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Net;
using System.Collections.Generic;

namespace Ekus
{

	/// <summary>
	/// Receives a web request with target URL, 
	/// invokes another web request to the target URL with added NTLM credentials, 
	/// and returns the response to the original caller.
	/// </summary>
	
	public class WebServiceProxy : IHttpHandler
	{
		public void ProcessRequest(HttpContext context)
		{
			string webServiceUrl = context.Request["url"].ToString();
			string proxy;
			// proxy = "127.0.0.1:8888"; used for testing with Fiddler2

			HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webServiceUrl);
			if (proxy != null) req.Proxy = new WebProxy(proxy, true);
			// if SOAPAction header is required, add it here...
			req.Headers.Add("SOAPAction", context.Request.Headers["SOAPAction"]);
			req.ContentType = "text/xml;charset=\"utf-8\"";
			req.Accept = "text/xml";
			req.Method = context.Request.HttpMethod; // "POST";
			req.Credentials = new NetworkCredential(
				"joker", // username; didn't work when using domain\username format
				"funny",  // password
				"gotham"); // domain
			req.PreAuthenticate = true; // Cargo_cult_programming

			if (req.Method == "POST")
			{
				// copy original request "body" to the new request
				string input = new StreamReader(context.Request.InputStream).ReadToEnd();
				// encode it using the predefined encoding (see above, req.ContentType)
				System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
				byte[] bytesToSend = encoding.GetBytes(input);
				// Set the content length of the string being posted.
				req.ContentLength = bytesToSend.Length;
				Stream newStream = req.GetRequestStream(); // This method has the side effect of initiating delivery of the request in its current state to the server. Any properties like the request method, content type or content length as well as any custom headers need to be assigned before calling the GetRequestStream() method.
				newStream.Write(bytesToSend, 0, bytesToSend.Length);
				// Close the Stream object.
				newStream.Close();
			} // else GET, no body to send. Other verbs are not supported at the moment.

			WebResponse resp = req.GetResponse();
			Stream respStream = resp.GetResponseStream();
			StreamReader r = new StreamReader(respStream);
			// process SOAP return doc here. For now, we'll just send the XML out to the browser ...
			string output = r.ReadToEnd();
			context.Response.Write(output);
		}

		public bool IsReusable
		{
			get
			{
				return false;
			}
		}
	}
}

2011-02-13 at 1:11 2 comments

The safest password

Today at work I was forced to change my silly, complicated Windows password: Pas$w0rdX to Pas$w0rdY.
That’s it. I changed one letter and called it a day. And not just any letter. The last letter. And I changed it in the least relevant way. I incremented it by a single bit. Looking at binary representation, this is my password before and after the change:

010100000110000101110011001001000111011100110000011100100110010001011000
010100000110000101110011001001000111011100110000011100100110010001011001

Looks like my network administrator hopes that in case my old password was about to be compromised by a hacker (for example by using the simplest method possible – trying all possible combinations one after another), he/she won’t be able to hack it now. Phew, disaster averted.

This ridiculous waste of time led me to idea: in order to make the hacking as difficult as possible, I will switch to

The Ultimate Safest Password

Of course I could make it idiotically long, but where is the fun in that? Instead, I will use the strongest password that fits in the minimum length, lets say 8 characters.

Looking at the binary representation of my previous and current password, the solution presents itself very easily:
If somebody tries to iterate all possible values, they will (obviously) start from 0 and increment it over and over. Thus, the binary form of the very last password to hack is…
1111111111111111111111111111111111111111111111111111111111111111

This password is guaranteed to be the most difficult 8-letter password to break using the most sophisticated KISS algorithm known to man (exactly 264 = 1.84467441 × 1019 iterations, as opposed to 5.7920372 × 1018 for the old password limited to 8 characters). That’s mind-bogglingly 3.18 times more secure (requires 3.18 x longer time to hack using very brute force).

But wait, there’s more!

Translating to decimal, it’s series of 8 bytes with value 255 (binary 11111111) each.
And now, the ultimatest safety haxx0r. Please turn on the NumLock key on your keyboard, and check the character that the code 255 produces:

First, you need to open Notepad and press and hold Left Alt, and then use the numeric keypad to type the character code. Tablet and Apple users should not apply, they don’t know what a numpad (nor a password) is:

Apple keyboard without numpad

The location of the new, magical Numeric Pad on the current Apple keyboard

Still holding that Alt key? Type 255 on the numeric keypad (while nothing happens) and… release the Alt key.

That’s it! Did you miss it? You just typed it! Code 255 produces an invisible space character!
Now, type it 7 more times.

invisible password in notepad

invisible password in notepad

Now, you can even save it on pendrive or print it and tape it to your desk. Your ultimate password is invisible and secure!

2011-02-10 at 22:07

Are there any windows in Windows Phone 7?

A friend made a pun about lack of windows in the incoming Windows Phone 7:

image

http://twitter.com/marcin_walus/status/27182240050

Funny, because there seem to be none. Also, even in Windows Mobile, the predecessor to WP7, they weren’t really used (the only “window” that I could drag was probably a MessageBox control). However, since the WM was based on Windows CE, which in turn was based (visually) on Windows 95… there are windows there, and you can even move them ;-)

[DllImport("coredll.dll")]
extern private static int MoveWindow(IntPtr hWnd,
int X, int Y, int nWidth, int nHeight, int bRepaint);

While I am sure that similar API is technically present (though not available) on Windows Phone (which is based on Windows CE, too), I have even better answer to the title question:

The phone itself is a window. A window to the world your data:

panorama-ctrl_3

Image by Stephane Crozatier, http://blogs.msdn.com/b/stephanc/archive/2010/04/04/windows-phone-7-panorama-control-sample.aspx

The suggested UI layout for most applications, called Panorama, shows it very clearly, by offering a seamless – yet modular – view. It would be even cooler, if you could pan or tilt your phone (or move your head, tracked by the ..gulp.. non-existing front-facing camera) to change the “point of view”. But dragging with fingers should do for now.

What’s that? You asked for plural windows? Damn…

2010-10-13 at 9:29

Automatyczne auta

Jakąś ironią jest, że coś co określamy mianem “auta” czy “samochodu” nie potrafi samo jeździć (podobnie jest z samolotem, ale to raczej kwestia formy w języku polskim, w przeciwieństwie do międzynarodowego określenia automobilu).

Ostatnio wpadłem na artykuł o kolejnych postępach w pracy nad nauczeniem aut samodzielności: Audi widmo nabiera kolorów.

Artykuł, czy raczej sam fakt, niezbyt odkrywczy, ale ciekawy. Niestety komentarze tradycyjnie są bardzo… kolorowe.
Choć sprowadzają się do tego, że przeterminowany GPS wpędzi te auta do stawu. Załatwione, nic nie zastąpi człowieka. Wpisujcie miasta!

Aż ziewać by się chciało, gdyby nie ilość i powszechność tak krótkowzrocznych komentarzy. Dla mnie perspektywa robotyzacji jest oczywistością tak oczywistą jak to, że lód w słońcu topnieje a dysk twardy jest zawsze za mały. Skąd się zatem biorą forumowi nay-sayers, w dodatku w każdym temacie i w dużych ilościach?

Czy to jest nasza polska cecha? Chrześcijańska? Zachodnia? Czegoś nie było w Biblii, konstytucji ojców-założycieli, lub w tradycji naszych własnych ojców, więc to nie istnieje i nie zaistnieje? Oczywiście używamy komórek, internetu, jakiś komputer na końcu świata przysyła nam sms-a przypominającego o wydarzeniu z google calendar, ale to przecież nie znaczy że postęp galopuje na naszych oczach..? Po prostu to pojawiło się nagle samo z siebie i już tak zostało. A wcześniejsze telefony, radia, pagery, telefony satelitarne – one też były chorymi pomysłami przez cały okres developmentu, testów i uczenia się na błędach?

Dlaczego nasz dziadek który powiedziałby swoim kolegom w podstawówce że jego wnuki będą mogły nie tylko za darmo czytać gazety z całego świata w sekundę po ich opublikowaniu, ale będą też mogły w każdej chwili napisać i opublikować swoje artykuły, zdjęcia, przemyślenia, i udostępnić je jednym gestem miliardom ludzi – dlaczego ten dziadek byłby przez kumpli wyśmiany lub oblany dla jaj atramentem?

(a propos miliardów – zastanawiam się kim jest ta druga – oprócz mnie – osoba, która wg statystyk codziennie czyta mojego bloga?)

Jest wiele tematów, dla mnie oczywistych, a które ku mojemu zdumieniu nie są oczywiste dla mojego otoczenia (niekoniecznie najbliższego, ale generalnie z tej planety):
Globalizacja, unifikacja i drastyczna redukcja ilości języków którymi porozumiewać się będą nasze pra-prawnuki (przy zachowaniu dużej liczby środowiskowych slangów, jednak wewnątrz wspólnej całości), powszechne modyfikacje genetyczne, klonowanie i projektowanie “sztucznego” życia, kontrola klimatu, eliminacja (czy też “zużycie się”) zarówno wszelkich religii jak i wojen, sztuczna inteligencja mądrzejsza od człowieka (i która go zastąpi w toku przewrotnie konsekwentnej ewolucji), są dla mnie tak samo nieuniknione (a dla wielu tak samo niedorzeczne) jak utrata przez Google dominującej pozycji na rynku wyszukiwarek.
Wake up, people! Czy nikt nie widzi ciągłości naszego rozwoju i – nade wszystko – jego kształtu i tendencji?

Uff, udało się wypocić kolejny wpis w tym półroczu. Zawsze lubiłem czerwiec.

2010-06-30 at 16:17

Simple .NET application testing with PowerShell

I had a need today to quickly test some functionality of an existing assembly. It is a part of a web app, but can be tested without a web context. It also could be (and partly is) tested using unit testing (nunit in this case). Unfortunately, I need to break some rules and manually modify the app’s environment during the test, to see how it reacts.

We (at my work) are using a relatively unpopular, yet very nice library for authorization management: Microsoft Authorization Manager, also called AzMan. Interestingly, it is a COM library with official Interop wrapper available, for which we have created yet another simple wrapper, to better interface with our system.

AzMan lets us define roles and operations, and then mix and match them to assign appropriate user privileges to our users. Its API is very simple, but it offers very flexible and elegant model. Obviously, we define some roles, such as salespeople and administrators, and assign users to them. What is particularly convenient for us is that we DO NOT hard-code any roles directly in our source:

if User.IsInRole("admin") or User.IsInRole("sales") 
then enableFeatureX

Instead, our developers only need to care about actual privileges:

if User.HasAccess(FeatureX) then enableFeatureX

 

This gives us great flexibility regarding actual roles. One day we can give some privilege to engineers, another day to salespeople, and even to a single user, if he is the boss’s son. I was surprised (ok, not really) to see how often business rules need to be changed in a company. Especially when we deploy our application at several locations, all with their little quirks and differences. The idea of abstract “scopes” in AzMan elevates us to a whole new level, where we can customize role definitions to be partly inherited from “global” roles, but adjusted to local needs. And all this without really recompiling the app.

For example, in a disk management system scopes can be folders or disks, in a company they can define divisions, or – like in our case – separate manufacturing sites. AzMan also allows us to use simple code inside a privilege check:

if cost>1000 then return false

Such snippets of code are called BizRules and offer even more flexibility without recompiling the actual app, but we decided to stick to simple true/false flags instead.

In our application we keep a simple definition of roles and privileges, called security policy, in AzMan-specific XML file, though there are other ways. When our application is loaded, we initialize a global AzMan model and create a security context for each user. The problem I worked on today is: Is AzMan aware of any changes made to the xml policy file after it has been initialized? I have read different opinions, but our experience showed that our web app had to be restarted to reload the file. Interestingly, there is a method in AzMan called UpdateCache, which we didn’t use, but which seemed to fit our needs.

Not wanting to play with recompilation of our actual complex app, I firstly used PowerShell to slip into the assembly and play around, dynamically calling some code.

I knew that PowerShell (object-aware command line on steroids) was by default included in Windows 7, but it turns out that also included is a nice PowerShell ISE (integrated scripting environment).

powershell in windows 7

Of course the ISE is not necessary to get started with PowerShell, as we can use a simple PowerShell console, but the tool is a nice step up. Oh, and it includes live console, anyway.

PowerShell ISE

The first  thing we need to do is to import the assembly:

[System.Reflection.Assembly]::LoadFile(
"C:\Path\To\Security.dll")

Then we need to instantiate the Model which in turn is used to create user context:

$model = New-Object Security.Model;
$model.AppLoaded;
# the above returns false

$model.LoadApp("msxml://C:\Policy.xml", "App");
$model.AppLoaded;
# now returns true

$user = $model.LoadCtx("S-1-XXX");
$user.HasAccess([Security.Operations]::AccessDenied, "");
# returns false, and always should, for everybody.

 

Now the nunit-unfriendly part: I quickly update the Policy.xml file (using azman.msc in Windows 7) and give the user with ID “S-1-XXX” access to operation “AccessDenied”.

Since my PowerShell session is still live, I can test $user.HasAccess again.

# now we can update the underlying policy file
# and run the commands below:

$user.HasAccess([Security.Operations]::AccessDenied, "");
# still returns false because policy has not been reloaded

 

Turns out, the change was not picked up by our little Security assembly. Luckily, all we need to do is to add a call to UpdateCache:

$model.UpdateCache();
$user.HasAccess([Security.Operations]::AccessDenied, "");
# returns true! success!

This way I have successfully tested my code. I only need to unassign the AccessDenied operation, since my real unit tests require it to be never used by anybody.
In addition, I’ve accomplished two more things:

  • learned PowerShell a tiny bit more
  • created script that could be automated for integration testing, if only it had some real value ;-)

All the script commands above can be called either from PowerShell console, one be one, or pasted into .ps1 file (PowerShell script). Of course, the .ps1 file will not wait for you to fiddle with the policy.xml file, so you would have to add the appropriate code yourself (either call to pause/sleep or some kind of xml poke for full automation).

P.S.

If you liked AzMan, you should take a look at NetSqlAzMan – open source implementation, without COM dependency but with very similar look&feel. I am considering upgrading to it from AzMan in the future.

2010-01-07 at 22:56

Clipboard image support in Silverlight

Clipboard text support is an obvious feature for silverlight, but clipboard image support could be silverlight’s “killer feature”, and help developers choose it over Air, Flash or javascript.

Continue Reading 2009-11-26 at 10:23

Sieciowe porządki, część 2: energooszczędny serwer

Jako geek mam wiele zboczeń, ale szczególnie cenię sobie to dotyczące ekologii, od czasów kiedy pacholęciem będąc poznawałem Bieszczady. Co prawda nie byłem harcerzem ani innym zorganizowanym skautem, ale dzięki odpowiedniej opiece i zachęcie udało mi się w czynie społecznym posadzić kilkaset drzew i wynieść z lasu podobną ilość porzuconych butelek.

Dlatego z ciężkim sercem słuchałem nieraz nocnego warczenia mojego komputera, który zużywał wiadro prądu, mimo że był obciążony zaledwie w kilku procentach podczas ściągania różnych… triali, dem i freeware’ów.

Rozwiązanie problemu zbiegło się w czasie z moją zabawą Home Serverem, choć nie od razu było ono wygodne. Przez pewien czas mój Windows Home Server działał jako maszyna wirtualna pod MS Virtual Serverem (zwykły MS Virtual PC nie obsługiwał dużych dysków). Był to podpięty przez USB 1-terabajtowy dysk WD Green Power (z tego co pamiętam, ciągnie on ok. 8 watów zamiast tradycyjnych(?) 10). Dzięki temu mój WHS – nieświadomy niczego – działał czasem “wewnątrz” netbooka, a czasem w ramach (w RAMie?) mojego desktopa. Owe 8W to jak dotąd mój rekord, w praktyce jednak rozwiązanie to było niedoskonałe, głównie za sprawą niskiego transferu i zabawy z wirtualnymi kartami sieciowymi (może uda mi się kiedyś napisać o tym więcej).

Aktualnie mój Chomik (WHS) działa bezpośrednio zainstalowany na wspomnianym netbooku i póki co jestem z tego rozwiązania zajebardzo dumny.

P1210738P1210743 P1210750 P1210764

Składniki:

  • netbook asus eee 900A, cena ok. 150-180 USD za refurbished. Free shipping w USA, opłaca się zwłaszcza kiedy trafi się darmowy przemyt ;-)
  • dysk 1TB Western Digital Green Power, ok 70-100 USD (300 PLN)
  • adapter mini-pci to SATA, opcjonalny bo można lutować SATA bezpośrednio do płyty ale adapter to dobry kompromis dla takich jak ja lutników. Bodajże 8 USD z przesyłką listem z Hong Kongu do Polski.
  • kabel+śledź eSATA do rozbiórki i lutowania, ok. 8 USD (25 PLN)
  • obudowa na dysk 3,5” USB+eSATA, ok. 30 USD (100 PLN). Częściowo opcjonalna, ważniejszy jest sam zasilacz 5V+12V.

W sumie ok. 300 USD, ale można taniej, zwłaszcza gdy niektóre części zalegają nam w szafie. Niestety po dodaniu kosztu licencji WHS (ok 100 USD) sprawa jest mniej fajna ale za to mamy bardzo energooszczędny serwer z MONITOREM (9”) i kul touchpadem multi-touch ;-), a w niektórych przypadkach także z bateryjnym podtrzymywaniem zasilania.
Co więcej system WHS wcale nie jest niezbędny, 80% jego funkcjonalności (torrent i NAS) można zrobić za darmo na Win XP czy innym Linuksie. Pozostałe 20% również, o ile kilka nieprzespanych nocy mamy też “za darmo”. Co osobiście uważam za bardzo kuszące, po tym jak WHS zawiódł mnie kilkakrotnie. Serwer przy normalnym użyciu nie przekracza 20 watów. Sam dysk zabiera 8,3 wata a monitor sporo poniżej 1.

Uwagi i nabyte doświadczenia:

  • podobno można zainstalować działający system Windows 2003 Server (czyli pewnie i WHS) tak, aby bootować z niego przez USB. Jednak SATA działa sporo szybciej i nie wymaga software’owego hackowania. A hackowanie hardware’owe jest jak wiadomo bardziej macho.
  • podłączenie SATA do płyty głównej lub do adaptera można zrobić prawie na ślepo (tzn. kolejność trzeba zachować, ale trudno czasem zgadnąć z której strony jest pin nr 1: http://pinouts.ru/HD/serialATA_pinout.shtml). Jest to 7 kabelków które jeśli się je podepnie odwrotnie, nic nie zrobią złego tylko nam nie wykryje dysku. Sprawdziłem, po przelutowniu w drugą stronę zadziałało. Oczywiście zasilanie to inna bajka ale tego nie hackowałem.
  • w przypadku mojego asusa – aby wykrył dysk SATA konieczne było zaktualizowanie BIOSu, bardzo proste (plik ROM na pendrive, boot).
  • z oczywistych względów warto podpiąć kablowy Ethernet zamiast WiFi (z drugiej strony wbudowane WiFi pozwala nam na zamurowanie serwera w ścianie lub pod wanną. Ale o tym zboczeniu innym razem).
  • Windows Home Server z powodzeniam działa jako zwykły domowy PC, z monitorem, kamerką USB, Youtubem, Winampem i Skypem.
  • W moim przypadku jest to zawsze włączony kuchenny skajpofon…
  • …oraz aktywowana ruchem zdalna kamera stojąca na straży lodówki – http://highlightcam.com/ ).
  • VNC to bardzo dobry zdalny dostęp do MONITORA serwera (zamiast osobnej sesji terminalowej). Można żonie rozłączyć skajpa. Aktualnie używam RealVNC bo jest częścią świetnego multi-instalatora http://ninite.com/
  • RealVNC choć instaluje się jako serwis w Windowsie, to nie dodaje siebie do wyjątków firewalla, trzeba to zrobić ręcznie (port 5900).
  • Zamiast dysku 3,5” bardzo warto rozważyć dysk 2,5”. Z moich kilkumiesięcznych doświadczeń wynika, że 500GB na spory czas wystarczy, później można uzbierać na drugi taki sam. Do SATA podpięty oczywiście bedzie tylko jeden, ale oba mogą ciągnąć prąd z USB, eliminując dodatkowy zasilacz 5V+12V…
  • albowiem eliminacja zasilacza dysku sprawia, że bateria w netbooku zadziała jak UPS, więc mamy serwer z prawdziwego zdarzenia, który się prędzej zahibernuje niż da zabić. To jest aktualnie mój drugi priorytet na liście ToDo.
  • dodatkowe dyski na USB mogą być 3,5-calowe, energożerne i bez UPSa, zwłaszcza gdy
    • potrafią/pozwalają się wyłączać podczas bezczynności
    • ewentualny zanik zasilania nie jest dla nich dużym problemem (przeważnie i tak są w spoczynku lub co najwyżej są odczytywane a nie zapisywane)
  • mój task numero uno to zainstalowanie TrueCrypta i zaszyfrowanie całego WHSa tak, jak to miało miejsce gdy Chomik był wirtualną maszyną w pliku .VHD
  • …niestety będzie to wymagało ode mnie (a przynajmniej będzie zalecało) lockowania konsoli, co jest niefajne w przypadku kuchennego komputera z kiepską/chowaną klawiaturą. Może czytnik odcisku palca załatwi sprawę, albo logowanie rozpoznawaniem twarzy przez kamerkę lub na podstawie bliskości telefonu z Bluetoothem. Niestety^2 wszystkie te rozwiązania podnoszą trochę zużycie energii.

Na koniec uwaga na temat niezawodności takiego zastosowania. Nie jest ono najwyższe, zwłaszcza w zasięgu dzieci które lubią kabelki; warto od razu pomyśleć o zamkniętej i unieruchomionej obudowie lub o innym zabezpieczeniu naszego zestawu. Z chwilą podpięcia do ethernetu nasz netbook przestaje być mobilny i musimy się z tym pogodzić. Darujmy sobie próby przestawiania, ustawiania, ciągłego rekonfigurowania. Wiem, bo dostałem nauczkę która nieomal kosztowała mnie dysk twardy i trochę danych. Najlepiej zamurować całość w ścianie. To jest mój trzeci task na liście ToDo :-)

2009-11-14 at 1:17 1 comment

Sieciowe porządki, część 1.

Zbliżająca się premiera Windows 7 to dobra okazja do wysprzątania komputerów. Na dodatek kilka miesięcy temu zacząłem zmagania z Windows Home Serverem, który w takich porządkach bardzo pomógł, choć w nieco złośliwy sposób. WHS ma dwie ogromne wady:

  • brak obsługi partycji nie-NTFS (czyli w moim przypadku netbooków na powolnych dyskach flash, gdzie FAT działa szybciej)
  • brak lub zła obsługa partycji zaszyfrowanych TrueCryptem na kliencie (nie można ich zaznaczyć do backupowania)

Jak się wkrótce okazało, ta druga niedogodność miała mnie kosztować utratę sporej porcji danych, kiedy to podczas instalacji (lub zaraz po) Windows 7 uznał sobie, że ta dziwna partycja RAW zajmująca pół dysku na pewno nie jest zagospodarowana i ją dla mnie sformatuje bez pytania.

image

W ten sposób zyskałem 300 GB wolnego miejsca, na szczęście wtedy już \\CHOMIK (mój WHS) był moim głównym repozytorium “ciężkich” danych (filmy, zdjęcia, muzyka), a firmowy laptop \\T60 zawierał wszystkie aktualne “Moje Dokumenty”. Mimo dwudniowej walki nie udało mi się odzyskać partycji TrueCrypta, co przyznaję z rezygnacją, bo  “wiem” jak to zrobić – brakuje mi tylko samozaparcia do napisania programu który sektor po sektorze wyszuka zapasowy header TrueCrypta (pierwszy jest uszkodzony a zapasowego sam TrueCrypt nie może zlokalizować) i zdekoduje go, odzyskując większość danych. Dysk 500GB na jakiś czas powędrował do szuflady, jak sobie przypomnę o czymś co warto jednak odzyskać to wrócę do tematu.

Doświadczenie to przyspieszyło moje porządki, ale też uświadomiło mi miłą rzecz: posiadanie WHS sprawiło, że ilość zduplikowanych danych na moich różnych komputerach bardzo się zmniejszyła. Teraz już wiem gdzie co jest lub gdzie powinno się wkrótce znaleźć. Dodatkowo okazało się, że moje komputery nie wymagają już dużych dysków, bo tą działką zajmuje się Chomik.

Offline files

Ostatnio ponownie odkryłem “killer feature” Windowsa 7, który co ciekawe był w Windowsie już od wersji 2000 :-)

Polega on na tym, że zamiast bawić się w synchronizację osobnymi programami typu Mesh, Groove, FolderShare, podłączam po prostu zasób sieciowy z mojego Chomika i zaznaczam opcję “Offline Files”. Powoduje to, że wszystkie dane zostaną nie tylko skopiowane i regularnie aktualizowane, ale też że Windows powiadomi mnie o ewentualnych konfliktach. Gdy dodatkowo zmapujemy zasób jako lokalny dysk, dostęp do niego staje się bardzo wygodny. Oczywiście przed WHS trudno było zdecydować jakie dane na którym komputerze powinny mieć swoje domyślne miejsce.

image image

image

Oczywiście ten sam zasób można podłączyć do wielu komputerów. Ponieważ nie planuję edytować np. plików Worda jednocześnie z żoną na osobnych komputerach, synchronizacja Offline Files w zupełności mi wystarcza.

Przy okazji grupowania danych do zasobów wykorzystałem jeszcze jedną ciekawą sztuczkę Windowsa – symlinki, czyli “dowiązania symboliczne”. W Windows 7 robi się je komendą mklink, w WHS trzeba dociągnąć Win2003 Resource Kit z komendą dlink:

mklink <nazwa linka>  <ścieżka>

np.

mklink C:\P  “C:\Program Files”

Triku tego używam czasem do skrócenia ścieżki Program Files podczas dodawania do zmiennej systemowej %path% – ma ona ograniczoną długość i wpisywanie w niej 20 razy “C:\Program Files” może prowadzić do problemów.

W Chomiku używam jej w innym celu – do zgrupowania różnych zasobów w jednym katalogu, który potem mapuję na innym komputerze. Wiąże się to z moim wstrętem do mapowania miliona (ok, 26) liter dysków do wszystkich możliwych zasobów, co jest jedną z głównych rozrywek administratorów sieci w korporacjach. Czyli zamiast mapować np.

I: –> \\Chomik\Users\Ekus
J: –> \\Chomik\Software\Install
K: –> \\Chomik\Video\Coding
L: –> \\Chomik\Video\Podcasts (nie chcę mapować całego Video ;-) )

mapuję tylko dwie rzeczy:

A: –> \\Chomik\Users\Ekus
B: –> \\Chomik\Links\T60

Na komputerze kuchennym oczywiście mapuję inny zestaw linków niż na firmowym laptopie, a część zasobów jest tam reużyta.

image

Na dzisiaj to tyle, gigabajty się ładnie synchronizują, pora zaczerpnąć jesiennego powietrza! Następnym razem napiszę więcej o moim hybrydowym – szyfrowanym – energooszczędnym Chomiku.

2009-09-27 at 13:14

Older Posts


RSS Unknown Feed

  • An error has occurred; the feed is probably down. Try again later.

RSS Unknown Feed

  • An error has occurred; the feed is probably down. Try again later.

Feeds

del.icio.us/Ekus