<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3404451797694685821</id><updated>2022-11-10T03:35:00.235+00:00</updated><category term="C#"/><category term="Ajax"/><category term="Fun"/><category term="Sql"/><category term="asp.net"/><category term="Vista"/><category term="Bug"/><category term="Mobile"/><category term="DDD Scotland"/><category term="Microsoft"/><category term="LCS"/><category term="Security"/><category term="Tips"/><category term="Visual Studio"/><category term="WCF"/><category term="Sharepoint"/><category term="Sql 2008"/><category term="UC"/><category term="Blogger"/><category term="Book Review"/><category term="Google"/><category term="Office 2007"/><category term="Videos"/><category term="Waterstons"/><category term="Webdd"/><category term=".net 2"/><category term=".net 3"/><category term=".net 3.5"/><category term="Apple"/><category term="Conference"/><category term="Control Tool Kit"/><category term="IPhone"/><category term="Javascript"/><category term="News"/><category term="Round Table"/><category term="SSIS"/><category term="Sidebar"/><category term="Voip"/><category term="fonebook"/><category term="Analysis Services"/><category term="Anonymous Methods"/><category term="Background Worker"/><category term="BarCamp"/><category term="BarCampNorthEast"/><category term="Barcode"/><category term="BizTalk"/><category term="CT360"/><category term="Code Works"/><category term="Debugging"/><category term="Delgates"/><category term="Design Pattern"/><category term="Feedburner"/><category term="Generics"/><category term="Hiring"/><category term="ICompare"/><category term="IE7"/><category term="IIS"/><category term="Image Manipulation"/><category term="Job"/><category term="Mesh"/><category term="Microformats"/><category term="Northpack"/><category term="Parse"/><category term="Presance"/><category term="Proper Case"/><category term="RainbowDuino"/><category term="Remote Debugging"/><category term="Role Provider"/><category term="Thinking Digital"/><category term="WHS drobo"/><category term="Windows Services"/><category term="arduino"/><category term="bbsb"/><category term="facebook"/><category term="jQuery"/><category term="msdn"/><category term="nanode"/><category term="windows forms"/><title type='text'>Development Diaries</title><subtitle type='html'>technology.selectNext();</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>120</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-9071996449227664313</id><published>2015-12-06T14:50:00.001+00:00</published><updated>2015-12-06T14:50:47.850+00:00</updated><title type='text'>PRTG as a Pachube/Cosm/Xively replacement?</title><content type='html'>Developer/Maker friendly long term data storage can be hard to come across but I think I have found a pretty neat solution.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-eR1-NSLOwk8/Vl9Lzzh2LoI/AAAAAAABS8Q/gIRXHOD6acc/s1600/screenshot.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;528&quot; src=&quot;http://4.bp.blogspot.com/-eR1-NSLOwk8/Vl9Lzzh2LoI/AAAAAAABS8Q/gIRXHOD6acc/s640/screenshot.PNG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;PRTG is a network monitoring tool produced by &lt;a href=&quot;https://www.paessler.com/prtg&quot;&gt;Paessler&lt;/a&gt;. It also allows ticket management and all sorts of very clever stuff that&#39;s totally over the top for a home user, but it does give you access to a really cool dashboard creating tool (see above), a load of built in sensors, the ability to add custom sensor it&#39;s totally free for up to 100 sensors. Before I jump ahead lets give your a brief overview of the terminology used in PRTG.&lt;br /&gt;&lt;h2&gt;What is a channel&lt;/h2&gt;A channel is basically a single data point. Each channel can have a value (a decimal normally), but it can also be a lookup with text as shown below. &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-KyL_P531aBI/Vl9VuwhBflI/AAAAAAABS8g/G6W_wfcscMs/s1600/status.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-KyL_P531aBI/Vl9VuwhBflI/AAAAAAABS8g/G6W_wfcscMs/s320/status.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;For each channel you can specify various options, but the most useful are Units (specifies the units for the thing you are measuring) &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-PXF57-hO2HI/Vl9ZIzBvesI/AAAAAAABS80/sj3t9Hbiw4M/s1600/ChannelSettings.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;http://1.bp.blogspot.com/-PXF57-hO2HI/Vl9ZIzBvesI/AAAAAAABS80/sj3t9Hbiw4M/s640/ChannelSettings.PNG&quot; width=&quot;532&quot; /&gt;&lt;/a&gt;&lt;/div&gt;You can also specify limits that cause the channel to switch state automatically (in this example a value above 90 will cause the sensor to be in error state). &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-w0yPzCv4WRc/Vl9Zw3PnYCI/AAAAAAABS84/xz0IbyJKldk/s1600/limits.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;352&quot; src=&quot;http://2.bp.blogspot.com/-w0yPzCv4WRc/Vl9Zw3PnYCI/AAAAAAABS84/xz0IbyJKldk/s640/limits.PNG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Finally you can do get some pretty nice graphs for each channel (this shows my energy usage for the last 2 days)&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-smV9rGIvlXk/Vl9chkSM3pI/AAAAAAABS9I/3AJLXunV-DE/s1600/energy.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;160&quot; src=&quot;http://1.bp.blogspot.com/-smV9rGIvlXk/Vl9chkSM3pI/AAAAAAABS9I/3AJLXunV-DE/s640/energy.PNG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2&gt;What is a sensor&lt;/h2&gt;A sensor is basically a collection of channels (up to 50 is recommended). It has an overall status of Ok, Warning or Error depending on the child channels. PRTG does a really nice job of summarizing the status of all your sensors. &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-sd8qgPZQPAE/Vl9Wo8Yph5I/AAAAAAABS8o/5_wi0Kn5JWQ/s1600/overallstatus.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-sd8qgPZQPAE/Vl9Wo8Yph5I/AAAAAAABS8o/5_wi0Kn5JWQ/s320/overallstatus.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;The sensor screen acts a bit like a dashabord for all the channels the sensor contains.&lt;br /&gt;&lt;h2&gt;What is a device&lt;/h2&gt;A device can have a collection of sensors that normally relate to the devices IP (but they don&#39;t have to). The device is clever in that it will automatically pause any sensors on it if some of the lighter weight sensors report an error condition (if for example it stops replying to ping) &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-J6_xn1vl3OI/VmRBprZ6RPI/AAAAAAABTE8/3nYejyTBQTI/s1600/ping.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-J6_xn1vl3OI/VmRBprZ6RPI/AAAAAAABTE8/3nYejyTBQTI/s320/ping.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;The device can also show a nice summary of the status of it&#39;s sensors &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-5SCOVtlejTI/VmRBwgXvBhI/AAAAAAABTFE/9MJgnmXTLPM/s1600/collapsed.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-5SCOVtlejTI/VmRBwgXvBhI/AAAAAAABTFE/9MJgnmXTLPM/s320/collapsed.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Device Groups&lt;/h2&gt;You can also group devices together like &quot;Windows Machines&quot; etc. Again the status of all the sensors below get grouped up. &lt;br /&gt;&lt;h2&gt;Notifications&lt;/h2&gt;You can out of the box configure PRTG to e-mail you (or push a notification to you) when a channel goes into a specific state.  &lt;br /&gt;&lt;h2&gt;Maps&lt;/h2&gt;This is perhaps my favourite feature! This lets you create really cool dashboards showing the status, and values of all the items above. Here for example is the map of my network &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-vd1LQ0BD61s/VmRDDSY4bDI/AAAAAAABTFQ/CXdm1JF8jqw/s1600/dashboard.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-vd1LQ0BD61s/VmRDDSY4bDI/AAAAAAABTFQ/CXdm1JF8jqw/s400/dashboard.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2&gt;Mobile App&lt;/h2&gt;Paessler have created amazingly complete applications for &lt;a href=&quot;https://www.paessler.com/apps/iosapp&quot;&gt;iOS&lt;/a&gt;, &lt;a href=&quot;https://www.paessler.com/apps/androidapp&quot;&gt;Android &lt;/a&gt;and even &lt;a href=&quot;https://www.paessler.com/apps/windowsphoneapp&quot;&gt;Windows Phone&lt;/a&gt;. The apps are very fully featured and make use of the native platforms (for example you can add sensors as widgets on android). As a mobile developer I&#39;m really happy to see this! &lt;br /&gt;&lt;h2&gt;Ok, what sort of things can you monitor&lt;/h2&gt;Out of the box there are over 200 sensors. I have mainly used the following:- &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Ping&lt;/b&gt; Pretty obvious, but lets you know if something has gone down quickly.&lt;/li&gt;&lt;li&gt;&lt;b&gt;HTTP&lt;/b&gt; Gives you average load times for a web page (used to monitor your internet connection)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Windows Sensors&lt;/b&gt; You can monitor a lot on a windows machine (CPU &amp;amp; memory usage, disk free space, uptime, pagefile usage, network traffic, RDP availability, is a service running), I use most of these!&lt;/li&gt;&lt;li&gt;&lt;b&gt;Network Flow&lt;/b&gt; If your router/switches support this (dd-wrt does!) then you can get a lot of information about the traffic flowing through your network. Really handy for IoT devices when you have no idea what they are doing!&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;What has &lt;i&gt;any&lt;/i&gt; of this go to do with makers&lt;/h2&gt;Nothing, because I haven&#39;t mentioned the best sensor types yet! PRTG also supports several custom sensors allowing you to monitor just about anything you want: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;EXE/Script&lt;/b&gt; You can write a console application that can output xml&lt;/li&gt;&lt;li&gt;&lt;b&gt;Python Script&lt;/b&gt; Same as above, but in python&lt;/li&gt;&lt;li&gt;&lt;b&gt;HTML XML/REST value&lt;/b&gt; This can poll a web api and do things like count the number of times an element appears. I use this to monitor how many people are streaming from my plex server&lt;/li&gt;&lt;li&gt;&lt;b&gt;HTTP Push Data&lt;/b&gt; Here you can push data to the server whenever an event happens that you would like to track (HOW COOL IS THAT!)&lt;/li&gt;&lt;/ul&gt;Obviously the above scripts could be used to interface with things like an Arduino really easily! The Paessler blog has listed some cool project makes have done using PRTG - here is a project that counts how much &lt;a href=&quot;https://www.paessler.com/blog/2015/11/24/all-about-prtg/prtg-letter-count-sensor&quot;&gt;mail you have received during the year&lt;/a&gt;, one that monitors &lt;a href=&quot;http://mawo24.de/sprit/&quot;&gt;fuel prices in Germany&lt;/a&gt; (and uses a nice dashboard to present the data). A hospital in South Australia is even using it to monitor blood bank levels and send alerts when they run low! Paessler have a great list showing some of the interesting things that are monitored using PRTG &lt;a href=&quot;https://www.paessler.com/campaign/monitoring-of-things&quot;&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;It&#39;s also really easy to configure PRTG to have custom notifications too. There are notifications for &lt;a href=&quot;http://prtgtoolsfamily.com/us/products/notifications/twitter&quot;&gt;Twitter&lt;/a&gt;, The terrorist favourite &lt;a href=&quot;http://kb.paessler.com/en/topic/65075-prtg-with-telegram&quot;&gt;Telegram&lt;/a&gt; and a load of &lt;a href=&quot;http://prtgtoolsfamily.com/downloads/notifications&quot;&gt;others&lt;/a&gt;, but it&#39;s really easy to add your own! &lt;br /&gt;&lt;br /&gt;So you basically have your own hosted version of Pachube/Cosm/Xively or whatever it&#39;s called now, plus it has ifttt type functionality (in-fact using the ifttt maker channel you could easily make the two work together nicely!) &lt;br /&gt;&lt;br /&gt;In the future I&#39;m going to blog a bit about some custom sensors I&#39;ve made, and a sensor host I&#39;m working on to make it really easy to use the HTML XML/Rest sensor! &lt;br /&gt;&lt;h2&gt;Ok, how much is it then&lt;/h2&gt;Ok, it&#39;s not cheap if you are going to be monitoring a lot of things, but it&#39;s totally free for the first 100 sensors! And each sensor can have up to 50 channels, so you could monitor up to 5,000 channels for free.  &lt;br/&gt; It used to be a lot less (10 sensors), but Paessler recently changed this in the hope that hobbyists/home network enthusiasts/geeks will love using this at home, and then tell the sys admins at work that they &lt;b&gt;need&lt;/b&gt; to be using this in the office. I can easily see how that would work, because this is first and foremost an excellent network monitoring tool, it just so happens to also be an excellent *insert your project here* monitoring tool too :-)</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/9071996449227664313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=9071996449227664313&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/9071996449227664313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/9071996449227664313'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2015/12/prtg-as-pachubecosmxively-replacement.html' title='PRTG as a Pachube/Cosm/Xively replacement?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-eR1-NSLOwk8/Vl9Lzzh2LoI/AAAAAAABS8Q/gIRXHOD6acc/s72-c/screenshot.PNG" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-1717488073318482197</id><published>2013-04-10T21:12:00.000+01:00</published><updated>2013-04-10T21:12:07.739+01:00</updated><title type='text'>Hacking a PacMan Lamp</title><content type='html'>&lt;p&gt;I recently got given a PacMan Lamp (which can be bought from &lt;a href=&quot;http://www.firebox.com/product/5542/Pac-Man-Ghost-Lamp&quot;&gt;Firebox&lt;/a&gt;) from microsoft because I published a windows store app (called &lt;a href=&quot;http://apps.microsoft.com/windows/en-us/app/phonics-space-race/5d7e6a1f-7f69-40c0-8f8b-3b9519416d77&quot;&gt;Space Race&lt;/a&gt; for those who are interested - its a phonics game for young children learning English!)&lt;/p&gt; &lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-zX2H464V3wk/UWR3IL_JCYI/AAAAAAAAA8Y/9VzXsrMGvFw/s320/p5542_extra1.gif&quot; /&gt; &lt;p&gt;The lamp comes with a little remote that lets you select any colour. I just had to figure out how to control this thing with an arduino!&lt;/p&gt; &lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-UvXVj4qnRek/UWWy_QE88HI/AAAAAAAAA8o/5RDqIYxYeHY/s320/p5542_extra3_column_grid_12.jpg&quot; /&gt; &lt;p&gt;I took the remote to bits, but quickly realized I was going to have to solder a wire per button at least, and this would hardly scale - so I decided the next best option would be to simulate the IR the remote produces.&lt;/p&gt; &lt;p&gt;Lady Ada has a brilliant &lt;a href=&quot;http://learn.adafruit.com/ir-sensor/testing-an-ir-sensor&quot;&gt;guide &lt;/a&gt;I used to read the IR signals via the arduino. To do this you will need a IR Detector, which I found to hand&lt;/p&gt; &lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-r2AKaF9j75M/UWW_pZvNRkI/AAAAAAAAA84/fySJ5Amsa8I/s320/WP_20130408_002.jpg&quot; /&gt; &lt;p&gt;Well, I say to hand... No kids toys were (permanently) broken you will be happy to hear&lt;/p&gt; &lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-Sxv2VVhJkVI/UWW_rPy2YJI/AAAAAAAAA9A/E1w8ELucXZA/s320/WP_20130408_001.jpg&quot; /&gt; &lt;p&gt;After hooking it all up to the Arduino I was able to pull out the timings of the &quot;On&quot; periods vs the &quot;Off&quot; periods. As advised you ignore the first off, and then look at the time periods for on vs off. It became pretty apparent that most times were around 530 µs, or 1620 µs, and the on periods were always the short time.&lt;/p&gt; &lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-UEed5SbpbHI/UWXA9nYx_5I/AAAAAAAAA9I/YDtrVOy1ckY/s320/Timings.PNG&quot; /&gt; &lt;p&gt;Once I had profiled several of the buttons I turned the &quot;Off&quot; periods into binary with the short period representing 0s, and the long periods representing 1s (as shown by column J in the screenshot above.&lt;/p&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-lha6xP2fLHk/UWXBikz4CpI/AAAAAAAAA9Q/tgQJdCRXJ5w/s320/codes.PNG&quot; /&gt;&lt;p&gt;With enough codes it became fairly obvious that the first 16 bits where always &quot;0000000011110&quot;, and the final 3 bits were always &quot;111&quot;. After scratching my head for a bit I realised that the first 5 bits, and the last 5 bits where the only things that changed (the middle bits where always &quot;000&quot;, and once I had pulled the bits that changed out it was really obvious that they were just the inverse of each other&lt;/p&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-kWbKyRHK4qo/UWXCYRy7exI/AAAAAAAAA9Y/AUA2B2yumaU/s320/pattern.PNG&quot; /&gt; &lt;p&gt;Now all I had to do was write an arduino script that would take 5 bits, and translate it into the code, and then correctly send it to the IR pins. Heavily borrowing from the sample code Lady Ada provided I was pretty easily able to implement the algorithm. Feel free to grab the code from my &lt;a href=&quot;https://github.com/rossdargan/Arduino-Projects/blob/master/PacManRemote/PacManRemote.ino&quot;&gt;GitHub repository&lt;/a&gt;. Once you have uploaded your code you will need to add an IR Diode to your arduino as shown in this image (ignore the stuff to the right of the image - thats for hooking up the IR Detector)&lt;/p&gt;&lt;a href=&quot;http://learn.adafruit.com/assets/592&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-QT6jpRzByhA/UWXENRwtsrI/AAAAAAAAA9k/KuUvYNHN9hs/s320/intervalometer.gif&quot; /&gt;&lt;/a&gt;(Image from Lady Ada&#39;s site)  &lt;p&gt;Now with everything loaded I needed to create a little app that would fire some commands at it. I created the following little library class that wraps everything up.&lt;/p&gt; &lt;script src=&quot;https://gist.github.com/rossdargan/5357928.js&quot;&gt;&lt;/script&gt; &lt;p&gt;To use it simply construct the object (passing in the com port the arduino is connected to, then call do command passing in a command you want) as shown below&lt;/p&gt;&lt;script src=&quot;https://gist.github.com/rossdargan/5357985.js&quot;&gt;&lt;/script&gt;&lt;p&gt;I&#39;d love to hear what you use this for - I have just hooked mine up to Lync (its like skype for business). It now flashes white and blue when I get a call and when I&#39;m not getting called it&#39;s coloured the same as my lync presence. I&#39;ll get a video up asap.&lt;p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/1717488073318482197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=1717488073318482197&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/1717488073318482197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/1717488073318482197'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2013/04/hacking-pacman-lamp.html' title='Hacking a PacMan Lamp'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-zX2H464V3wk/UWR3IL_JCYI/AAAAAAAAA8Y/9VzXsrMGvFw/s72-c/p5542_extra1.gif" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-39907672980678535</id><published>2011-12-22T20:44:00.000+00:00</published><updated>2013-04-10T21:15:10.633+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arduino"/><category scheme="http://www.blogger.com/atom/ns#" term="bbsb"/><category scheme="http://www.blogger.com/atom/ns#" term="nanode"/><title type='text'>A BBSB Online controller clone (for £26)</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/--RHTf7UgZ6I/TvOXtN0yQLI/AAAAAAAAA4s/LLlfCNtITaU/s1600/31Ptn-dKAgL._SL500_AA300_.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear:right; float:right; margin-left:1em; margin-bottom:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; width=&quot;300&quot; src=&quot;http://4.bp.blogspot.com/--RHTf7UgZ6I/TvOXtN0yQLI/AAAAAAAAA4s/LLlfCNtITaU/s400/31Ptn-dKAgL._SL500_AA300_.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;  I love home automation (as I&#39;m sure any geek does!), so when I saw the &lt;a href=&quot;http://www.domialifestyle.com/BBS_Range.asp&quot;&gt;BBSB online controller&lt;/a&gt; I knew I needed it in my life but could really justify the £90, plus I figured why not try and build one myself. I mean, how hard can it be? &lt;br/&gt;&lt;br/&gt;First thing I needed was some programmable hardware and since I have done so many arduino based projects before, the choice was obvious. Or was it? I noticed a new arduino clone had popped onto the market called a &lt;a href=&quot;http://nanode.eu/&quot;&gt;Nanode&lt;/a&gt;. Acting much like an arduino but at an incredible &lt;a href=&quot;http://www.skpang.co.uk/catalog/nanode-kit-p-973.html&quot;&gt;£22 from SK Pang&lt;/a&gt; (a similar arduino is &lt;a href=&quot;http://www.skpang.co.uk/catalog/arduino-ethernet-without-poe-p-954.html&quot;&gt;over £44!&lt;/a&gt;). Now I actually ended up getting the upgraded model (&lt;a href=&quot;http://www.skpang.co.uk/catalog/nanode-rf-kit-868mhz-p-1020.html&quot;&gt;Nanode RF&lt;/a&gt;) which includes the following extra features:- &lt;br/&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;A Hope RF RFM12B (supplied with 868MHz module) transceiver for 2 way communications with other boards.&lt;/li&gt;&lt;li&gt;A microSD card for general datalogging storage, storing applications and webpages. microSD card not supplied.&lt;/li&gt;&lt;li&gt;A realtime clock IC with alarm function which also holds a unique ID. not supplied.&lt;/li&gt;&lt;li&gt;An 8 pin socket (under the H logo) to allow you to add non volatile RAM for program download. Supplied with 23K256 256kb SRAM and DIL socket.&lt;/li&gt;&lt;/ul&gt;&lt;br/&gt;This allows me to use it to talk to other devices, but more on that in a later blog post! &lt;br/&gt;&lt;br/&gt;To simulate the bye bye standbye online controller I needed to know 2 things. 1 how does it talk to the sockets, and 2 how does it receive commands from app such as the brilliant &lt;a href=&quot;http://itunes.apple.com/gb/app/remote-for-bye-bye-standby/id319582493?mt=8&quot;&gt;remote for Bye Bye Standbye&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Well thankfully both problems have been solved, and well documented many times before! &lt;br/&gt;&lt;br/&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-Kw9XYNJiREE/TvOWa-onXII/AAAAAAAAA4g/x-kcqn82pJ8/s1600/433.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear:right; float:right; margin-left:1em; margin-bottom:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; width=&quot;238&quot; src=&quot;http://4.bp.blogspot.com/-Kw9XYNJiREE/TvOWa-onXII/AAAAAAAAA4g/x-kcqn82pJ8/s400/433.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt; Arduino actually have a &lt;a href=&quot;http://arduino.cc/playground/Code/HomeEasy&quot;&gt;playground for all of the HomeEasy&lt;/a&gt; integration code - so that was the easy bit. The only additional thing I needed was something that could &quot;talk&quot; over the 433 frequency. Thankfully &lt;a href=&quot;http://uk.farnell.com/jsp/search/productdetail.jsp?sku=1699488&amp;amp;CMP=i-bf9f-00001000&quot;&gt;Farnell sell one for a smidge of £4&lt;/a&gt;.   &lt;br/&gt;&lt;br/&gt;Once I proved I could get this working nicely (using code &lt;a href=&quot;http://arduino.cc/playground/Code/HomeEasy?action=sourceblock&amp;amp;num=3&quot;&gt;sample 3&lt;/a&gt; from the playground) I moved on to problem 2 - how does the BBSB controller talk to other software? &lt;br/&gt;&lt;br/&gt;Again this was (unusually) well &lt;a href=&quot;http://www.byebyestandby.co.uk/forum/viewtopic.php?f=6&amp;amp;t=57&amp;amp;sid=f3479eb1e0670f5c48c44baf0abd5f75&quot;&gt;published &lt;/a&gt;by bye bye standanby (hats off to you for that!). So all I had to do was get the nanode to &quot;talk&quot; UDP. &lt;br/&gt;&lt;br/&gt;Well this was a tad harder! The Nanode does not use the same Ethernet chip as the Ardiuno Ethernet stuff - so you can&#39;t use the standard &quot;Ethernet&quot; Library. Arduino recently released a new version of their IDE (V1) this means a lot of the code samples online have changed so it&#39;s a tiny bit harder to get good samples, but with some great help from the nanode community (&lt;a href=&quot;http://webchat.freenode.net/?channels=nanode&quot;&gt;get involved on irc&lt;/a&gt;) I was able to pull apart the &lt;a href=&quot;https://github.com/thiseldo/EtherCardExamples/blob/master/EtherCard_TFTPServer/EtherCard_TFTPServer.ino&quot;&gt;tftp&lt;/a&gt; sample and just handle the udp packets I needed. &lt;br/&gt;&lt;br/&gt;So without further ado here is my code hosted on github (my first open source code!) &lt;a href=&quot;https://github.com/rossdargan/Arduino-Projects/blob/master/BBSBControllerImpersonator/BBSBControllerImpersonator.ino&quot;&gt;https://github.com/rossdargan/Arduino-Projects/blob/master/BBSBControllerImpersonator/BBSBControllerImpersonator.ino&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;And here is the final solution:- &lt;br/&gt;&lt;br/&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-YLnMi8lhkRA/TvOSz-QvbHI/AAAAAAAAA4U/FWRuCOWITMU/s1600/IMG_1440.JPG&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; src=&quot;http://4.bp.blogspot.com/-YLnMi8lhkRA/TvOSz-QvbHI/AAAAAAAAA4U/FWRuCOWITMU/s400/IMG_1440.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;h2&gt;Testing&lt;/h2&gt;&lt;p&gt;BBSB also provide a really handy application to test to see if everything works fine - you can grab that from &lt;a href=&quot;http://www.byebyestandby.com/forum/viewtopic.php?f=6&amp;t=304&quot;&gt;the forums&lt;/a&gt;&lt;h2&gt;Future changes&lt;/h2&gt;&lt;p&gt;Well the Nanode RF already includes a transmitter so it&#39;s a bit daft not to be using it - unfortunately it&#39;s the wrong frequency - but you can easily by a compatible 433 transiever from &lt;a href=&quot;http://uk.farnell.com/rf-solutions/alpha-trx433s/module-transceiver-trx433s/dp/1718689&quot;&gt;farnell&lt;/a&gt;. &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/39907672980678535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=39907672980678535&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/39907672980678535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/39907672980678535'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2011/12/a-bbsb-online-controller-clone-for-26.html' title='A BBSB Online controller clone (for £26)'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/--RHTf7UgZ6I/TvOXtN0yQLI/AAAAAAAAA4s/LLlfCNtITaU/s72-c/31Ptn-dKAgL._SL500_AA300_.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-385152429582740468</id><published>2011-11-01T19:54:00.008+00:00</published><updated>2011-11-03T15:57:23.092+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WHS drobo"/><title type='text'>Announcing WHS Drobo Status!</title><content type='html'>&lt;a href=&quot;http://3.bp.blogspot.com/-hW3diXNiS8Y/TrBPBOqw30I/AAAAAAAAA3U/Qu6iHIxydxA/s1600/drobo3.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 75px; height: 69px;&quot; src=&quot;http://3.bp.blogspot.com/-hW3diXNiS8Y/TrBPBOqw30I/AAAAAAAAA3U/Qu6iHIxydxA/s400/drobo3.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5670118813395377986&quot; /&gt;&lt;/a&gt;I have always loved Microsoft&#39;s Windows Home Server and sing its praises whenever possible; however with the most recent version Microsoft decided to remove what I always thought was one of the best features - the drive extender!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://www.drobo.com/&quot;&gt;Drobo &lt;/a&gt;as a product is a perfect fit for this gap. The product allows you to add multiple hard drives and collates the space, making it easy for a home user to expand their storage space on demand.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I always wanted a Drobo so when I saw a competition running on the &lt;a href=&quot;http://homeservershow.com/the-drobo-whs-add-in-challenge.html&quot;&gt;Home Server Show&#39;s&lt;/a&gt; website to win one I knew I had to enter!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The competition required the development of an add-in for Windows Home Server (something I have always wanted to do but couldn&#39;t quite think of anything to build!) So, having put sleep aside for a few days I&#39;m very pleased to announce the public beta of my WHS Drobo plugin!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The plugin allows you to at-a-glance view how much space you have available, and the status of the drives as shown below:-&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;http://4.bp.blogspot.com/-X1tpSlhuGM0/TrBQVOGdomI/AAAAAAAAA3g/WkPEpa-sqp4/s400/droboPlugin.PNG&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5670120256352133730&quot; style=&quot;cursor: pointer; width: 400px; height: 325px; &quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The screenshot below shows the drive information if for example you remove a disk:-&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src=&quot;http://1.bp.blogspot.com/-n5c9PVYy-mo/TrBRPwRrjDI/AAAAAAAAA3s/GJ283it0f50/s400/DriveLost.PNG&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5670121261958401074&quot; style=&quot;cursor: pointer; width: 284px; height: 242px; &quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can find the beta here: &lt;a href=&quot;http://homeservershow.com/forums/index.php?/files/category/7-whs-drobo-status/&quot;&gt;WHSDroboStatus.wssx&lt;/a&gt;. Simply install the add-in as normal from any WHS client computer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Please note &lt;/b&gt;you must have the Drobo dashboard software installed on your Windows Home Server for the plugin to work (you probably have it installed already! If not you can find the right version from the &lt;a href=&quot;http://www.drobo.com/support/updates.php&quot;&gt;drobo website&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Any request for new features/feedback can be added here: &lt;a href=&quot;http://whsdrobo.uservoice.com/&quot;&gt;http://whsdrobo.uservoice.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Please also leave a comment to let me know how you get on with it!&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/385152429582740468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=385152429582740468&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/385152429582740468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/385152429582740468'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2011/11/announcing-whs-drobo-status.html' title='Announcing WHS Drobo Status!'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-hW3diXNiS8Y/TrBPBOqw30I/AAAAAAAAA3U/Qu6iHIxydxA/s72-c/drobo3.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-6866509201428668382</id><published>2010-09-03T22:52:00.001+01:00</published><updated>2010-09-03T22:56:10.400+01:00</updated><title type='text'>B&amp;Qs Cubo Colour changing LED cube</title><content type='html'>&lt;p&gt;I was in b&amp;amp;q and I spotted one of these:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TIFuAnKr-BI/AAAAAAAAAww/3p3UyNP4XLc/s1600-h/IMG_0184%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0184&quot; border=&quot;0&quot; alt=&quot;IMG_0184&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TIFuBNXvA5I/AAAAAAAAAw0/5sBigEK0oRI/IMG_0184_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TIFuBo7bbYI/AAAAAAAAAw4/nfyMzSsFI78/s1600-h/IMG_0187%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0187&quot; border=&quot;0&quot; alt=&quot;IMG_0187&quot; src=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/TIFuCLmExaI/AAAAAAAAAw8/dSQyXM5PdSk/IMG_0187_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TIFuCgppzFI/AAAAAAAAAxA/swPb-pIouis/s1600-h/IMG_0186%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0186&quot; border=&quot;0&quot; alt=&quot;IMG_0186&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TIFuDLaGcUI/AAAAAAAAAxE/hhiPZjNQYGc/IMG_0186_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TIFuDl7wBQI/AAAAAAAAAxI/QSa8dCFlVcw/s1600-h/IMG_0185%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0185&quot; border=&quot;0&quot; alt=&quot;IMG_0185&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TIFuEGg-QxI/AAAAAAAAAxM/k4DVLKsvwmA/IMG_0185_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TIFuEokM9NI/AAAAAAAAAxQ/e4Rzte8xJMg/s1600-h/IMG_0183%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0183&quot; border=&quot;0&quot; alt=&quot;IMG_0183&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TIFuFEdLSAI/AAAAAAAAAxU/W57JDUY_8oM/IMG_0183_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It was reduced down to £1.50 – but I can only find them in store not on the web, so no linky I’m afraid!&lt;/p&gt;  &lt;p&gt;The cube light is pretty small at around 5cm each side, but produces a fairly nice light.&lt;/p&gt;  &lt;p&gt;To remove the bottom part requires a bit of force as its glued in place but once you do pry it apart you are presented with a single LED with two legs connected to a switch, then a 22 ohm resister +/-5% followed by 3 * 1.5v AG13 batteries. It looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TIFuFxW800I/AAAAAAAAAxY/zFH2gw7Ju1A/s1600-h/IMG_0189%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_0189&quot; border=&quot;0&quot; alt=&quot;IMG_0189&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TIFuGGUD9AI/AAAAAAAAAxc/qIyWa7S-w1w/IMG_0189_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;At this point I realised something clever must be happening– all of them colours via only 2 pins! If you look very closely at LED you will notice on the top of the anode leg inside the led a tiny black dot. That dot is what controls the colour, so hacking this is going to be extremely limited if you intend on using this LED.&lt;/p&gt;  &lt;p&gt;Whilst it’s currently driven from the 4.5v provided by the batteries I did successfully drive the unit from the 3.3v from a neduino board , so you could very easily use it as some form of output. Powering it externally also means it will last a lot longer than the 6-8 hours the leaflet expects it to last from the batteries – and given the batteries cost £1.89 from Amazon (more than the device cost!) it’s a good job!&lt;/p&gt;  &lt;p&gt;I think that the best bet if you were hacking this device would be to replace the current in place IC controlled LED with a RGB LED. The plastic Plug holding all the gubbings also comes with a hole which could easily fit any cables you needed to bring out of the device!&lt;/p&gt;    &lt;p&gt;Happy Hacking!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/6866509201428668382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=6866509201428668382&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/6866509201428668382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/6866509201428668382'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2010/09/b-cubo-colour-changing-led-cube.html' title='B&amp;amp;Qs Cubo Colour changing LED cube'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_XNLFf_IbM28/TIFuBNXvA5I/AAAAAAAAAw0/5sBigEK0oRI/s72-c/IMG_0184_thumb.jpg?imgmax=800" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-7871325346650376164</id><published>2010-08-20T10:51:00.001+01:00</published><updated>2010-08-20T12:55:55.402+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LCS"/><category scheme="http://www.blogger.com/atom/ns#" term="RainbowDuino"/><category scheme="http://www.blogger.com/atom/ns#" term="UC"/><title type='text'>Rainbowduino + Microsoft Office Communicator</title><content type='html'>&lt;h2&gt;The Project&lt;/h2&gt; &lt;p&gt;Create a Cube Grenade with a rainbowduino I had lying about. Cube grenades can be described as:&lt;/p&gt; &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;This, I believe, is where my cartoons work the best- “Cube Grenades”- small objects that you “throw” in there in order to cause some damage- to start a conversation, to spread an idea etc&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href=&quot;http://gapingvoid.com/2009/05/13/cube-grenades/&quot;&gt;http://gapingvoid.com/2009/05/13/cube-grenades/&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;Since I work at a small company (around 60 employees) I could use the 8*8 grid to display peoples communicator status.&lt;/p&gt; &lt;h2&gt;The Parts&lt;/h2&gt; &lt;p&gt;A rainbowduino is an LED driver platform which can control an RGB matrix. It looks like this:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TG5P80HHPcI/AAAAAAAAAus/cLPaMj9XePI/s1600-h/rainbowduino_LRG%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;rainbowduino_LRG&quot; border=&quot;0&quot; alt=&quot;rainbowduino_LRG&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TG5P9DaOOlI/AAAAAAAAAuw/_qjEh1KyAVg/rainbowduino_LRG_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; height=&quot;184&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Since it’s basically an arduino you can replace the default firmware with a custom one and make it do what you want.&lt;/p&gt; &lt;p&gt;The next item is the RGB matrix itself:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/TG5P95RkvdI/AAAAAAAAAu0/ryNdwefk570/s1600-h/IMG_2850%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;IMG_2850&quot; border=&quot;0&quot; alt=&quot;IMG_2850&quot; src=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TG5P_K5oZRI/AAAAAAAAAu4/_v4YU5lrhr8/IMG_2850_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; height=&quot;184&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This slots into the rainbowduino perfectly&lt;/p&gt; &lt;p&gt;Finally I needed some way to flash/communicate with the rainbowduino. Effectively you need a USB to serial convertor. &lt;/p&gt; &lt;p&gt;I decided upon a seeedstudio UartSB to make it as easy as possible (this also allows you to create a wireless connection via Xbee should you want to!)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TG5P_v-679I/AAAAAAAAAu8/FM1m6XB6W-w/s1600-h/uartsb_LRG%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;uartsb_LRG&quot; border=&quot;0&quot; alt=&quot;uartsb_LRG&quot; src=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TG5QAu-GjSI/AAAAAAAAAvA/WauXTdLbd7s/uartsb_LRG_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; height=&quot;184&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The pins also line up perfectly with the rainbowduino so it’s ideal for this project.&lt;/p&gt; &lt;p&gt;I also bought a harness because it came with a&amp;#160; 2.1mm DC jack to pin plug adapter (which is what the rainbowduino needs for to power it), and I paid extra for an arduino power supply when I bough my arduino.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TG5oq_jfYWI/AAAAAAAAAvQ/akLXDB2oRWA/s1600-h/hns13.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;hns1&quot; border=&quot;0&quot; alt=&quot;hns1&quot; src=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/TG5orNF7VlI/AAAAAAAAAvU/vbYuPGtq1TA/hns1_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; height=&quot;184&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I got most of my parts from &lt;a href=&quot;http://www.skpang.co.uk&quot;&gt;www.skpang.co.uk&lt;/a&gt; and at the time (March 09) they cost:&lt;/p&gt; &lt;ul&gt;   &lt;li&gt;&lt;a href=&quot;http://www.skpang.co.uk/catalog/product_info.php?products_id=461&quot;&gt;Rainbowduino LED driver platform&lt;/a&gt;= £15.99 &lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.skpang.co.uk/catalog/product_info.php?products_id=392&quot;&gt;60mm Square 8x8 RGB LED Matrix&lt;/a&gt;= £19.67 &lt;/li&gt;    &lt;li&gt;UartSB V2.1= £20.13 (No longer available) &lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.skpang.co.uk/catalog/product_info.php?products_id=390&quot;&gt;Harness for arudino&lt;/a&gt; = £5.76 &lt;/li&gt;    &lt;li&gt;&lt;a href=&quot;http://www.skpang.co.uk/catalog/product_info.php?cPath=140_141&amp;amp;products_id=364&quot;&gt;Arduino PSU&lt;/a&gt; = £9.99 &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Total: £71.54&lt;/p&gt; &lt;p&gt;Ok, so it’s an expensive toy, but I have used them for other projects (including writing minesweeper for the rainbowduino!)&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;p&gt;Please note that you can use an arduino to flash and communicate with the rainbowduino instead of the UartSB as shown in this image:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TG5QBvvfFfI/AAAAAAAAAvE/2ft0L0FhFh8/s1600-h/arduino_rainbowduino%5B2%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;arduino_rainbowduino&quot; border=&quot;0&quot; alt=&quot;arduino_rainbowduino&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TG5QCf1sSkI/AAAAAAAAAvM/kZ7feJxQPiM/arduino_rainbowduino_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; height=&quot;180&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.rngtng.com/2009/06/25/rainbowduino-here-it-is-and-how-to-program-it/&quot;&gt;http://www.rngtng.com/2009/06/25/rainbowduino-here-it-is-and-how-to-program-it/&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;The Idea&lt;/h2&gt; &lt;p&gt;I had a play about with getting OCS statuses and decided that the easiest way would be to use COM to connected to a local Communicator client, get all the statuses and send them via the usb serial port to the rainbowduino.&lt;/p&gt; &lt;p&gt;I could have saved it to a database and used an ethernet shield to get the data, but I decided since a machine would have to be on to get the statuses anyway I might as well just use the easiest method.&lt;/p&gt; &lt;h2&gt;The Rainbowduino Program&lt;/h2&gt; &lt;p&gt;The first thing I had to get working was the rainbowduino. The firmware it comes with is pretty good, but you have to use I2C to send it instructions and the firmware doesn’t allow you to specify an individual pixels colour.&lt;/p&gt; &lt;p&gt;The firmware was a really good starting place for me, but I hade to modify it quite a bit. By default the rainbowduino starts with a pretty screen, but I wanted it to start with every light turned off. This can be achieved by modifying the multi dimensional array in the data.c file.&amp;#160; The array is defined as follows:&lt;/p&gt; &lt;p&gt;unsigned char dots_color[5][3][8][4] = {…}&lt;/p&gt; &lt;p&gt;This array allows for a buffer (up to 5 different images can be buffered) the three colours, and the individual data for each row/column.&lt;/p&gt; &lt;p&gt;so to set the first two pixels to green you would set the following:&lt;/p&gt; &lt;p&gt;dots_color[Buffprt][0][0][0] = 0xff&lt;/p&gt; &lt;p&gt;A pointer to the screen currently being displayed is stored in the variable Buffprt. the next 0 refers to green, (1=red, 2=blue). The next 0 refers to the first row, and the final 0 refers to the first two LEDS on the first row.&lt;/p&gt; &lt;p&gt;The column gets complicated because it uses a byte (8 bits) to define two LEDs. This is a really clever way of saving memory, but it does get complicated!&lt;/p&gt; &lt;p&gt;To turn the first LED you would use the bits 00001111 (0Xf) and for the second LED you would use 11110000 (0xf0).&lt;/p&gt; &lt;p&gt;Once I understood this I could write a setpixel function with the following signature:&lt;/p&gt; &lt;p&gt;void SetPixel(byte red, byte green, byte blue,&amp;#160; unsigned char rowToSet, unsigned char columnToSet)&lt;/p&gt; &lt;p&gt;I liked the idea of the buffer, so the first thing I do is copy the current buffer into the next frame – this means the rainbowduino will never forget current statues, and will only modify the led we want to change. It’s important to note that this really isn’t required and you could just modify the current frame.&lt;/p&gt; &lt;pre class=&quot;csharpcode&quot;&gt;  unsigned &lt;span class=&quot;kwrd&quot;&gt;char&lt;/span&gt; color=0,row=0,dots=0;&lt;br /&gt;  &lt;br /&gt;   &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt;(color=0;color&amp;lt;3;color++)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (row=0;row&amp;lt;8;row++)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (dots=0;dots&amp;lt;4;dots++)&lt;br /&gt;      {                 &lt;br /&gt;         dots_color[((Buffprt+1)&amp;amp;1)][color][row][dots] = dots_color[((Buffprt))][color][row][dots];  &lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;p&gt;The next thing I had to do was find out which column we are actually setting – for example if the row we are trying to set is the last LED on a row we would pass in 7 (LEDs are 0 indexed). This would translate to column 3, and the last 4 bits on this byte.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lets say the 6’th and 7th LED were currently 1/2 on, and we wanted to turn the 7th LED fully on. this would mean that the byte was currently:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00110011&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What we need to do is create a mask that will blank out the first four bits, and then or it with the value we want to set.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So in our example the mask would be:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00001111&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We would and the mask with the current value leaving:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00110011&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;amp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00001111&lt;/p&gt;&lt;br /&gt;&lt;p&gt;=&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00000011&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We then need to add in the new value of the LED. We do this by first bit shifting our input (0xf) and then or’ing it with the above value.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;e.g.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;1111 &amp;lt;&amp;lt; 4 (0xf bit shited 4 places)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;=&lt;/p&gt;&lt;br /&gt;&lt;p&gt;11110000&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We then or this with the original byte value after it has been and’ed with the mask.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;00000011&lt;/p&gt;&lt;br /&gt;&lt;p&gt;|&lt;/p&gt;&lt;br /&gt;&lt;p&gt;11110000&lt;/p&gt;&lt;br /&gt;&lt;p&gt;=&lt;/p&gt;&lt;br /&gt;&lt;p&gt;11110011&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is exactly the result we want. This is all achieved with the following code:&lt;/p&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt; boolean firstBit = columnToSet % 2==0;&lt;br /&gt;  columnToSet = columnToSet/2;&lt;br /&gt;   &lt;br /&gt;  Value = red;&lt;br /&gt;  Mask = 0xf0;&lt;br /&gt;  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt;(firstBit)&lt;br /&gt;  {&lt;br /&gt;    Value=red&amp;lt;&amp;lt;4; &lt;br /&gt;    Mask=0x0f;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  color=1;&lt;br /&gt;  Value = (dots_color[Buffprt][color][rowToSet][columnToSet] &amp;amp; Mask) | Value;    &lt;br /&gt;  dots_color[((Buffprt+1)&amp;amp;1)][color][rowToSet][columnToSet] = Value;&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;p&gt;This is repeated for the other two colours.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Finally all we have to do is tell the current buffer to move on by one.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now that we have written the setpixels method we need to write some way to communicate with our rainbowduino via the serial port.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is done via the following code:&lt;/p&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; loop()&lt;br /&gt;{&lt;br /&gt;    unsigned &lt;span class=&quot;kwrd&quot;&gt;char&lt;/span&gt; color=0,row=0,dots=0;&lt;br /&gt;         &lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (Serial.available() &amp;gt; 0) {&lt;br /&gt;      &lt;span class=&quot;rem&quot;&gt;// read the incoming byte:&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt;  red = Serial.read();&lt;br /&gt;      delay(2);&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; blue = Serial.read();&lt;br /&gt;      delay(2);&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; green = Serial.read();&lt;br /&gt;      delay(2);&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; row = Serial.read();&lt;br /&gt;      delay(2);&lt;br /&gt;      &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; column = Serial.read();&lt;br /&gt;       &lt;br /&gt;      &lt;span class=&quot;rem&quot;&gt;// say what you got:&lt;/span&gt;&lt;br /&gt;      Serial.print(&lt;span class=&quot;str&quot;&gt;&amp;quot;I received: &amp;quot;&lt;/span&gt;);&lt;br /&gt;      Serial.print(red);&lt;br /&gt;      Serial.print(&lt;span class=&quot;str&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;);&lt;br /&gt;      Serial.print(blue);&lt;br /&gt;      Serial.print(&lt;span class=&quot;str&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;);&lt;br /&gt;      Serial.print(green); &lt;br /&gt;      Serial.print(&lt;span class=&quot;str&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;);&lt;br /&gt;      Serial.print(row); &lt;br /&gt;      Serial.print(&lt;span class=&quot;str&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;);&lt;br /&gt;      Serial.println(column);&lt;br /&gt;      SetPixel(red, blue, green,  row, column);&lt;br /&gt;      Serial.println(&lt;span class=&quot;str&quot;&gt;&amp;quot;sent&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }  &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;There is a delay between reading the value in the Serial port to ensure the next value is in the buffer. But the code is pretty simple. It listens for 5 bytes of data then pushes the result into the SetPixel method we created before. As long as the data doesn’t get send to quickly it works fine, but this is pretty nasty code and I’m sure there are better ways of doing this.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The Office Communicator Software&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;The integration with OCS is quite easy. By downloading the &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=ed1cce45-cc22-46e1-bd50-660fe6d2c98c&amp;amp;displaylang=en&quot;&gt;SDK&lt;/a&gt; then adding a reference to CommunicatorAPI you can get all the statuses you need.The code below attaches allt eh events we will require, logs in, then does the initial load of the contacts&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;CommunicatorAPI.MessengerClass _messenger;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; OCSInterface()&lt;br /&gt;{&lt;br /&gt;    _messenger= &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; CommunicatorAPI.MessengerClass();&lt;br /&gt;    _messenger.OnContactStatusChange += &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DMessengerEvents_OnContactStatusChangeEventHandler(_messenger_OnContactStatusChange);&lt;br /&gt;    _messenger.OnIMWindowContactAdded += &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DMessengerEvents_OnIMWindowContactAddedEventHandler(_messenger_OnIMWindowContactAdded);&lt;br /&gt;    _messenger.OnIMWindowContactRemoved += &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DMessengerEvents_OnIMWindowContactRemovedEventHandler(_messenger_OnIMWindowContactRemoved);&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (_messenger.MyStatus != MISTATUS.MISTATUS_ONLINE)&lt;br /&gt;    {&lt;br /&gt;        _messenger.AutoSignin();&lt;br /&gt;    }&lt;br /&gt;    LoadContacts();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;p&gt;Because we don’t really want to be dealing with iMessengerContacts in other bits of code I translate the objects into a Plain Old CLR Object defined below:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;   &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Contact&lt;br /&gt;    {&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; FriendlyName { get; set; }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; SipAddress { get; set; }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Status Status { get; set; }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Row { get; set; }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Column { get; set; }&lt;br /&gt;    }&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;enum&lt;/span&gt; Status&lt;br /&gt;    {&lt;br /&gt;        Offline =0,&lt;br /&gt;        Online=1,&lt;br /&gt;        Busy=2,&lt;br /&gt;        Away=3,&lt;br /&gt;        Idle,&lt;br /&gt;        Phone&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This shows the different status I’m going to be using, and also shows the pixel the contact relates to.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The load contact method does this translation and is shown below:&lt;/p&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, Contact&amp;gt; _contacts = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;, Contact&amp;gt;();&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; LoadContacts()&lt;br /&gt;{        &lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (CommunicatorAPI.IMessengerContact messengerContact &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; (_messenger.MyContacts &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; CommunicatorAPI.IMessengerContacts))&lt;br /&gt;    {&lt;br /&gt;        Contact contact = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Contact();&lt;br /&gt;        contact.FriendlyName = messengerContact.FriendlyName;&lt;br /&gt;        contact.Status = Status.Busy;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;switch&lt;/span&gt; (messengerContact.Status)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_OFFLINE:&lt;br /&gt;                contact.Status = Status.Offline;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_ONLINE:&lt;br /&gt;                contact.Status = Status.Online;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_AWAY:&lt;br /&gt;                contact.Status = Status.Away;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_IDLE:&lt;br /&gt;                contact.Status = Status.Idle;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;default&lt;/span&gt;:&lt;br /&gt;                contact.Status = Status.Busy;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        contact.SipAddress = messengerContact.SigninName;&lt;br /&gt;        _contacts.Add(contact.SipAddress, contact);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;As you can see the pixel location is not set here, this is done when we actually interface with the rainbowduino.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The most import event we attached to on the MessengerClass was the contactstatuschange event. This lets us know when we need to update the rainbowduino. The code simply identifies the Contact POCO object, and updates the status.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In a great example of shocking code I have duplicated the mapping between my POCO status and the messenger status – this should have been a private method – but this isn’t production code and I can’t be bothered to change it! At the end of the call we notify an event that the status has changed, and we should notify the rainbowduino.&lt;/p&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ContactStatusChanged(Contact changedContact);&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;event&lt;/span&gt; ContactStatusChanged onStatusChanged;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; _messenger_OnContactStatusChange(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; pMContact, MISTATUS mStatus)&lt;br /&gt;{&lt;br /&gt;    Contact contact=  _contacts[((CommunicatorAPI.IMessengerContact)pMContact).SigninName];&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;switch&lt;/span&gt; (mStatus)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_OFFLINE:&lt;br /&gt;                contact.Status = Status.Offline;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_ONLINE:&lt;br /&gt;                contact.Status = Status.Online;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_AWAY:&lt;br /&gt;                contact.Status = Status.Away;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_IDLE:&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_OUT_OF_OFFICE:&lt;br /&gt;                contact.Status = Status.Idle;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; MISTATUS.MISTATUS_ON_THE_PHONE:&lt;br /&gt;                contact.Status= Status.Phone;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;default&lt;/span&gt;:&lt;br /&gt;                contact.Status = Status.Busy;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (onStatusChanged != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        onStatusChanged(contact);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;p&gt;The other two events we attach to respond to the event “IMWindowContactAdded” – this basically means starting and IM chat with someone. I added this as I wanted a way to tell who related to which pixel and this was the easiest way of adding that.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; _messenger_OnIMWindowContactRemoved(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; pContact, &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; pIMWindow)&lt;br /&gt;{&lt;br /&gt;    Contact contact = _contacts[((CommunicatorAPI.IMessengerContact)pContact).SigninName];&lt;br /&gt;&lt;br /&gt;    _messenger_OnContactStatusChange(pContact, ((CommunicatorAPI.IMessengerContact)pContact).Status);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; _messenger_OnIMWindowContactAdded(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; pContact, &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; pIMWindow)&lt;br /&gt;{            &lt;br /&gt;    _messenger_OnContactStatusChange(pContact,MISTATUS.MISTATUS_ON_THE_PHONE);&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;p&gt;The class I use to interface with the rainbowduino simply opens a serial connection on a port, and sends the required colour and pixel location to the rainbowduino. Notice I have abstracted the colours from rgb to system.drawing.color – this just makes it a bit easier to call the code, however I haven’t implemented every colour, so if a color gets send which isn’t implement it gets translated into Black.&lt;/p&gt;&lt;br /&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; RainbowInterface :IDisposable&lt;br /&gt;{&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; _portName = &lt;span class=&quot;str&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;    SerialPort port;&lt;span class=&quot;rem&quot;&gt;// = new SerialPort(_portName);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; RainbowInterface(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; portName)&lt;br /&gt;    {&lt;br /&gt;            port = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SerialPort(portName);&lt;br /&gt;&lt;br /&gt;        _portName = portName;&lt;br /&gt;        port.BaudRate = 9600;&lt;br /&gt;        port.DataReceived += &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SerialDataReceivedEventHandler(port_DataReceived);&lt;br /&gt;&lt;br /&gt;        port.Open();&lt;br /&gt;    }&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SetPixel(System.Drawing.Color color, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; row, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; column)&lt;br /&gt;    {&lt;br /&gt;        SetPixel(color, row, column, &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SetPixel(System.Drawing.Color color, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; row, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; column, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; showHighlight)&lt;br /&gt;    {&lt;br /&gt;            &lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; bRed = 0x0; &lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; bBlue = 0x0;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; bGreen =0x0;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color ==System.Drawing.Color.Blue)&lt;br /&gt;        {&lt;br /&gt;            bBlue = 0xf;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Red)&lt;br /&gt;        {&lt;br /&gt;            bRed = 0xf;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Green)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0xf;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Yellow)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0xf;&lt;br /&gt;            bRed = 0xe;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Purple)&lt;br /&gt;        {&lt;br /&gt;            bRed = 0xf;&lt;br /&gt;            bBlue = 0xf;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Aqua)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0x1;&lt;br /&gt;            bBlue = 0x1;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.LightBlue)&lt;br /&gt;        {&lt;br /&gt;            bBlue = 0x8;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Salmon)&lt;br /&gt;        {&lt;br /&gt;            bRed = 0x1;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.LightGreen)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0x8;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.Orange)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0x2;&lt;br /&gt;            bRed = 0xe;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (color == System.Drawing.Color.White)&lt;br /&gt;        {&lt;br /&gt;            bGreen = 0xf;&lt;br /&gt;            bRed = 0xf;&lt;br /&gt;            bBlue = 0xf;&lt;br /&gt;             &lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (showHighlight)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt; blueFade = 0xF;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;while&lt;/span&gt; (blueFade &amp;gt; 0 &amp;amp;&amp;amp; blueFade &amp;lt;= 0xF)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt;[] bytesBlue = { 0x0, 0x0, blueFade, System.BitConverter.GetBytes(row)[0], System.BitConverter.GetBytes(column)[0] };&lt;br /&gt;&lt;br /&gt;                port.Write(bytesBlue, 0, bytesBlue.Length);&lt;br /&gt;&lt;br /&gt;                System.Threading.Thread.Sleep(40);&lt;br /&gt;                blueFade -= 2;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;byte&lt;/span&gt;[] bytes = { bRed, bGreen, bBlue, System.BitConverter.GetBytes(row)[0], System.BitConverter.GetBytes(column)[0] };&lt;br /&gt;        port.Write(bytes, 0, bytes.Length);&lt;br /&gt;        System.Threading.Thread.Sleep(50);&lt;br /&gt;        &lt;span class=&quot;rem&quot;&gt;// port.Write(sRed+sGreen+sBlue + row + column);&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; port_DataReceived(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; sender, SerialDataReceivedEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(port.ReadLine());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;preproc&quot;&gt;#region&lt;/span&gt; IDisposable Members&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;    {&lt;br /&gt;        port.Close();&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;preproc&quot;&gt;#endregion&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Notice I have also added a highlight animation. This just helps show which pixel has been updated.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The last bit of code is what ties everything together.&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; PresencePoller.RainbowInterface _rainbowInterface;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; PresencePoller.OCSInterface _cinterface;&lt;span class=&quot;rem&quot;&gt;// = new PresencePoller.OCSInterface();        &lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Main(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        _rainbowInterface =  &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; PresencePoller.RainbowInterface(args[0]);            &lt;br /&gt;        _cinterface= &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; PresencePoller.OCSInterface();&lt;br /&gt;&lt;br /&gt;            _cinterface.onStatusChanged += &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; PresencePoller.OCSInterface.ContactStatusChanged(cinterface_onStatusChanged);&lt;br /&gt;            IEnumerable&amp;lt;PresencePoller.Contact&amp;gt; contacts = _cinterface.GetContacts();&lt;br /&gt;&lt;br /&gt;            var contactsOrdered = contacts.OrderBy(p =&amp;gt; p.FriendlyName);&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; row = 0;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; column = 0;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (var contact &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; contactsOrdered)&lt;br /&gt;            {&lt;br /&gt;                contact.Row = row;&lt;br /&gt;                contact.Column = column;&lt;br /&gt;&lt;br /&gt;                SetStatus(contact);&lt;br /&gt;&lt;br /&gt;                column++;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (column == 8)&lt;br /&gt;                {&lt;br /&gt;                    column = 0;&lt;br /&gt;                    row++;&lt;br /&gt;                }&lt;br /&gt;                Console.WriteLine((&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt;)contact.Status);&lt;br /&gt;            }&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;while&lt;/span&gt; (row &amp;lt; 8)&lt;br /&gt;            {&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Aqua, row, column);&lt;br /&gt;                column++;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (column == 8)&lt;br /&gt;                {&lt;br /&gt;                    column = 0;&lt;br /&gt;                    row++;&lt;br /&gt;                }&lt;br /&gt;            }                &lt;br /&gt;            Console.ReadLine();&lt;br /&gt;            &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; cinterface_onStatusChanged(PresencePoller.Contact changedContact)&lt;br /&gt;    {&lt;br /&gt;        SetStatus(changedContact);&lt;br /&gt;    }&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt;  &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SetStatus(PresencePoller.Contact contact)&lt;br /&gt;    {&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;switch&lt;/span&gt; (contact.Status)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Away:&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Orange, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Busy:&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Red, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Offline:&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Salmon, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Idle:&lt;br /&gt;                &lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Yellow, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Phone:&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.White, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; PresencePoller.Status.Online:&lt;br /&gt;                _rainbowInterface.SetPixel(System.Drawing.Color.Green, contact.Row, contact.Column);&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;All this code does is on load loop through every POCO contact, assign a pixel to the user, then notify the rainbowduino of its status. Then anytime the status changes we update the rainbowduino again.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The final Result&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TG5oruQCmjI/AAAAAAAAAvY/PSGJNEcPQ6c/s1600-h/IMG_0062%5B3%5D.jpg&quot;&gt;&lt;img style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px&quot; title=&quot;IMG_0062&quot; border=&quot;0&quot; alt=&quot;IMG_0062&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/TG5or-GfWBI/AAAAAAAAAvc/7hDv-V56zaM/IMG_0062_thumb.jpg?imgmax=800&quot; width=&quot;183&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:c700227f-d780-42c3-9cd2-ea422b6c29a0&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;div id=&quot;9100de43-17d6-4c08-98b7-c9eecc793c66&quot; style=&quot;margin: 0px; padding: 0px; display: inline;&quot;&gt;&lt;div&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=Mau4n-gw9iM&amp;amp;feature=youtube_gdata_player&quot; target=&quot;_new&quot;&gt;&lt;img src=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/TG5osN9wWBI/AAAAAAAAAwA/9l3PLH2PgzY/videof9c305d5f9a1%5B35%5D.jpg?imgmax=800&quot; style=&quot;border-style: none&quot; galleryimg=&quot;no&quot; onload=&quot;var downlevelDiv = document.getElementById(&#39;9100de43-17d6-4c08-98b7-c9eecc793c66&#39;); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/Mau4n-gw9iM&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/Mau4n-gw9iM&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;width:425px;clear:both;font-size:.8em&quot;&gt;Please note the paper is used to make the LED colours a bit easier to see&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Future Enhancements&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Instead of passing the red, green, and blue separately I could have combined two of the colours by a similar bit shifting method as used in the buffer – I didn’t for readability, however it would have been 20% quicker to transfer data if I did make this improvement. &lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;My aim was to build a cube grenade, not something useful, and I think I have succeeded in doing this. I have lost count of the number of people that have seen this and said “Why would you do that, its pointless – but you could do this with it…” &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Job done&lt;img style=&quot;border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; alt=&quot;Smile&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/TG5osgrvacI/AAAAAAAAAvk/W7pJ1mhwCTY/wlEmoticon-smile%5B2%5D.png?imgmax=800&quot; /&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/7871325346650376164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=7871325346650376164&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7871325346650376164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7871325346650376164'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2010/08/rainbowduino-microsoft-office.html' title='Rainbowduino + Microsoft Office Communicator'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_XNLFf_IbM28/TG5P9DaOOlI/AAAAAAAAAuw/_qjEh1KyAVg/s72-c/rainbowduino_LRG_thumb.jpg?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-7558551622658950158</id><published>2009-10-13T16:43:00.003+01:00</published><updated>2009-10-13T16:56:00.781+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tips"/><title type='text'>Multiple monitors &amp; windows 7</title><content type='html'>Windows 7 has a great new feature called &quot;aero snap&quot;  that lets you drag a window to the left or right of the screen and have it resize to that position (see here for a video of this &lt;a href=&quot;http://lifehacker.com/5077728/snap-any-window-to-half-the-screen-size-in-windows-7&quot;&gt;http://lifehacker.com/5077728/snap-any-window-to-half-the-screen-size-in-windows-7&lt;/a&gt;). &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is great feature except if you have multiple monitors. Areo Snap won&#39;t snap correctly to the part of the screen that goes across your monitors.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can work round this by holding down the windows key and pressing the arrow key for the direction you would like to snap in (e.g. if your window is on monitor 1 then press the start key and right and will will snap to the right part of monitor 1)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Perfect! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;P.S. Also don&#39;t forget you can press the start key up to maximize, down to minimize and you can use the number keys to select items from the start bar to maximize them (or bring them to the foreground)&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/7558551622658950158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=7558551622658950158&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7558551622658950158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7558551622658950158'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2009/10/multiple-monitors-windows-7.html' title='Multiple monitors &amp; windows 7'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8351272774109222744</id><published>2009-10-01T15:52:00.000+01:00</published><updated>2009-10-01T15:53:16.727+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="jQuery"/><title type='text'>jQuery and asp.net</title><content type='html'>&lt;p class=&quot;MsoNormal&quot;&gt;There are many ways to get asp.net control values from javascript. Here are a couple of ways with pro’s/cons&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;Normal Javascript:&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;document.getElementById(&lt;span style=&quot;color:maroon&quot;&gt;&#39;ctl00_ContentPlaceHolder1_TextBox1&#39;&lt;/span&gt;).value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;This is massivly hard coded and bad. If you change the content place holder, or refactor this into a user control this will no longer work. But this is quick.&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;document.getElementById(&lt;span style=&quot;color:maroon&quot;&gt;&#39;&lt;%=TextBox1.ClientID %&gt;&#39;&lt;/span&gt;).value&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;This is less hard coded which is good, but the code can be a bit tricky to read.&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;With jQuery:&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;$(&lt;span style=&quot;color:maroon&quot;&gt;&#39;#ctl00_ContentPlaceHolder1_TextBox1&#39;&lt;/span&gt;)[0].value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;Again, just as bad as the first normal Javascript example&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;$(&lt;span style=&quot;color:maroon&quot;&gt;&#39;#&lt;%=TextBox1.ClientID %&gt;&#39;&lt;/span&gt;)[0].value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;This is ok compared to the javascript version&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;$(&lt;span style=&quot;color:maroon&quot;&gt;&#39;input[id$=TextBox1]&#39;&lt;/span&gt;)[0].value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;This is probably my favorite method. This tells jquery to search for an input where the id ends with TextBox1 – be careful you have no other TextBox1 ids on the page!&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;Note the array indexer. This is because jquery returns an array of all the items it finds. This means if you have a grid with 12 rows you can access all of the textbox1’s using &lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;$(&lt;span style=&quot;color:maroon&quot;&gt;&#39;input[id$=TextBox1]&#39;&lt;/span&gt;)[0].value -&gt; $(&lt;span style=&quot;color:maroon&quot;&gt;&#39;input[id$=TextBox1]&#39;&lt;/span&gt;)[12].value&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;Now you are probably asking why would you just use the first javascript example. This is reasonable for a text box but say you are using a drop down list – which looks better:&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot; style=&quot;text-autospace:none&quot;&gt;&lt;span style=&quot;font-size:10.0pt; font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;    &lt;span style=&quot;color:blue&quot;&gt;var&lt;/span&gt; CustomerInputbox = document.getElementById(&lt;span style=&quot;color:maroon&quot;&gt;&#39;&lt;%=ddlCustomer.ClientID %&gt;&#39;&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;    &lt;span style=&quot;color:blue&quot;&gt;var&lt;/span&gt; CustomerID = CustomerInputbox.options[CustomerInputbox.selectedIndex].value;&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;or&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;span style=&quot;font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;&quot;&gt;    &lt;span style=&quot;color:blue&quot;&gt;var&lt;/span&gt; CustomerID = $(&lt;span style=&quot;color:maroon&quot;&gt;&#39;select[id$=ddlCustomer] option:selected&#39;&lt;/span&gt;)[0].value&lt;/span&gt;&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;That is all.&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;Ross&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;P.S. Learn to love jQuery, resistance is futile.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8351272774109222744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8351272774109222744&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8351272774109222744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8351272774109222744'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2009/10/jquery-and-aspnet.html' title='jQuery and asp.net'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8194456639227923376</id><published>2009-05-20T09:28:00.003+01:00</published><updated>2009-05-20T09:32:18.419+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Waterstons"/><title type='text'>What don&#39;t you know?</title><content type='html'>As part of the review process at Waterstons we have to set objectives to try and achieve throughout the coming year. I want to orientate mine around stuff I didn&#39;t know but wanted to know - here is my list:-&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Large scale architecture &amp;amp; design: &lt;/b&gt;Probably some kind of training course&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Cloud Computing&lt;/b&gt;: Microsoft have a beta product called Asure which could offer us the ability to produce some very innovative and scalable solutions.&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Microsoft enterprise library application blocks&lt;/b&gt;: these include code to make the following easier (and best practice): Caching, Cryptography, data access, logging and security. &lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Code generation:&lt;/b&gt; Learn more about the code generation techniques we are using&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Sql&lt;/b&gt;: My sql skills are purely self taught and there are loads of advanced techniques I just don’t know (not really sure how I would self learn this, I do know I have very little knowledge in SSIS).&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Visual Studio 2010 &amp;amp; .net 4.0:&lt;/b&gt; This will be with us soon and I couldn’t really tell you what we will be getting (the beta is out now) &lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;ADO.Net data services&lt;/b&gt;: a colleague sent an email around about these – I think they could be quite a different way for us to consume sql information.&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;BI tools&lt;/b&gt;: I know the theory behind BI but not the tools &lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Test Driven Development&lt;/b&gt;: The tools could be useful, but I’m really not sold on this&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;ASP.Net Routing&lt;/b&gt;: This technology allows us to create .net web sites which are search engine optimised (SEO) &lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;ASP.NET MVC&lt;/b&gt;: This is a different way of developing web applications that is gaining a lot of momentum – could easily become industry standard and Microsoft are putting a lot of money and resources into it.&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;ASP.Net data driven websites&lt;/b&gt;: Creates the scaffolding for data driven sites – should do things like code generation but this is from Microsoft&lt;/p&gt;  &lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;FX Cop/StyleCop:&lt;/b&gt; These tools perform analysis on source code to identify potential coding issues&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;It&#39;s really interesting to write a list like this - it defiantly helps organise your (lack of!) free time a bit better - what would be on your list?&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8194456639227923376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8194456639227923376&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8194456639227923376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8194456639227923376'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2009/05/what-dont-you-know.html' title='What don&#39;t you know?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-4971608883203865280</id><published>2009-03-26T17:47:00.001+00:00</published><updated>2009-03-26T17:57:46.090+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="BizTalk"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><title type='text'>Securing Anonymous web services with Certificates</title><content type='html'>&lt;p&gt;We are currently working with a client who requires two BizTalk web services to talk to each other, however because they are in different locations there is no common account we can use to secure the communication. Below shows an example of the setup:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;BizTalk Server 1:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/Scu_sEVkMfI/AAAAAAAAAbc/L_FJ91_t9HY/s1600-h/image%5B3%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;280&quot; alt=&quot;image&quot; src=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/Scu_siH0TnI/AAAAAAAAAbg/7zrQEsB7eU4/image_thumb%5B1%5D.png?imgmax=800&quot; width=&quot;424&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This orchestration has an input port (which accepts an xml file) – this message is then passed to a request reply port (which will call a webservice hosted on BizTalk server 2). The response is then passed to the output port (which is saved to an xml file).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;BizTalk server 2:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/Scu_s-OM_EI/AAAAAAAAAbk/rUA1DXnNpO4/s1600-h/image%5B8%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;288&quot; alt=&quot;image&quot; src=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/Scu_tRjycLI/AAAAAAAAAbo/E70U1J207ao/image_thumb%5B4%5D.png?imgmax=800&quot; width=&quot;434&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;This orchestration is a simple webservice which accepts a message, does something with the contents and returns the new message.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;This posting assume you have two orchestrations already talking to each other using wcf without any authentication&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Ok that’s the scenario defined – lets get onto the more interesting part! &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuring BizTalk server 1 (The WCF consumer):&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Since we are going to be securing the webservice with certificates lets start by generating the client certificate. Run the following code on the server which will be connecting to the webservice (BizTalk server 1 in my case) in a command prompt:&lt;/p&gt; &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;makecert -r -pe -n &lt;span class=&quot;str&quot;&gt;&amp;quot;CN=ClientCertName&amp;quot;&lt;/span&gt; -b 01/01/2005 -e 01/01/2100 -sky exchange -ss my&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;To view the certificate type mmc into command prompt, then go to file add/remove snap in, and select Certificates. You should be given an option to select select who you will be managing the certificates for – select “My user account”&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/Scu_uKBu7pI/AAAAAAAAAbs/VNmCp21CKEU/s1600-h/image%5B12%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;261&quot; alt=&quot;image&quot; src=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/Scu_upCxOoI/AAAAAAAAAbw/BxOKZUZ0ius/image_thumb%5B6%5D.png?imgmax=800&quot; width=&quot;431&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now if you look in the Personal folder you should see your certificate. We will need to install this same certificate in a few other places so right click on it and select export. Ensure you include the private key (you actually don&#39;t need the private key on the BizTalk server hosting the webservice, but for this demo I have included it).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we need to install this certificate in two different locations. On BizTalk server 1 we need to install it under the user account running the host instance. To do this open up a command prompt and type: &lt;/p&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;pre class=&quot;csharpcode&quot;&gt;runas /user:DOMAINNAME\USERNAME mmc&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;then type the password for the user. In the management console again select the certificate add in. You can then import the certificate by right clicking on personal and selecting import.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we can configure this server to use the certificate you have added. Go into the send port you have generated and ensure you used the type wcf-wshttp – then click configure. For the address modify the url to use Https, then go to the security tab. Here you want to change the security mode to Transport with transport client type: certificate. Then in the client certificate panel click browse. Here you should be able to select the certificate you have just generated.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;That’s the first server configured.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Configuring Server 2 (The WCF Provider):&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;On the second server go to the receive location and select your WCF port. Click configure and go to Security. Set the security mode to Transport, and the client credential type to Certificate.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/Scu_vJzRkpI/AAAAAAAAAb0/0s0Kpz6qBNw/s1600-h/image%5B17%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;415&quot; alt=&quot;image&quot; src=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/Scu_v-V2k8I/AAAAAAAAAb4/B4tE6FxqgxU/image_thumb%5B9%5D.png?imgmax=800&quot; width=&quot;310&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we need to configure IIS to host the ssl web service. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Firstly we will need to get another certificate to allow ssl to occur – so right click on the web site and go to properties, then Directory Security and click server certificate. Click the “Create a new certificate” and next followed by “Prepare the request now, but send it later” (You may be able to click send the request immediately to an online certification authority depending on your setup) Fill in all the details ensuring the field named “Common Name” is the dns name used to connect to this machine from Server 1. This will generate a text file which you can then give to a certificate authority to get a valid ssl certificate (this will have to be a certificate authority trusted by Server one – so possible a public authority like VeriSign).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Once you have your certificate you should be able to add it by re-running the above wizard.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now what we need to do is install the client certificate generated on server 1 – ensure this is installed into the Local Computer certificate store so IIS can access it. Remember for security this certificate should not really include the private key.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;After you have added your certificate click the edit button shown below &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_XNLFf_IbM28/Scu_wNfr80I/AAAAAAAAAb8/zPqCFanEQL8/s1600-h/image%5B21%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;179&quot; alt=&quot;image&quot; src=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/Scu_wgcE1aI/AAAAAAAAAcA/kjX52uTSse0/image_thumb%5B11%5D.png?imgmax=800&quot; width=&quot;413&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Then select the following “Require Secure Channel”, “Require Client Certificates” and “Enable Certificate Trust List”, then click New...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This Wizard will allow you to specify the client certificates which can be used to access the webservice. Click Add from store then select the client certificate installed above. Click next, give it a friendly name, next and Finish. Then select the certificate list:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/Scu_xSc7ymI/AAAAAAAAAcE/60wJ_xefR2g/s1600-h/image%5B26%5D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;399&quot; alt=&quot;image&quot; src=&quot;http://lh6.ggpht.com/_XNLFf_IbM28/Scu_xg4E1yI/AAAAAAAAAcI/167bmILNrh8/image_thumb%5B14%5D.png?imgmax=800&quot; width=&quot;422&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;You will probably have to restart IIS now before this works correctly (and I had to restart IIS every time I changed the certificate trust list).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And thats it! Transport security with client certificates DONE.&lt;/p&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;p&gt;Here are some error messages you might get and how to fix them:&lt;/p&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;The adapter failed to transmit message going to send port &lt;span class=&quot;str&quot;&gt;&amp;quot;SendPort1&amp;quot;&lt;/span&gt; with URL &lt;span class=&quot;str&quot;&gt;&amp;quot;https://ServerName/TestWebserviceCommunication/TestWebserviceCommunication_ProcessMessage_SendAndRecieve.svc&amp;quot;&lt;/span&gt;. It will be retransmitted after the retry interval specified &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; Send Port. Details:&lt;span class=&quot;str&quot;&gt;&amp;quot;System.InvalidOperationException: Cannot find the X.509 certificate using the following search criteria: StoreName &#39;My&#39;, StoreLocation &#39;CurrentUser&#39;, FindType &#39;FindByThumbprint&#39;, FindValue &#39;23D68B9999C21FC93702D259736DD0CC1C752B61&#39;.&lt;br /&gt;   at System.ServiceModel.Security.SecurityUtils.GetCertificateFromStoreCore(StoreName storeName, StoreLocation storeLocation, X509FindType findType, Object findValue, EndpointAddress target, Boolean throwIfMultipleOrNoMatch)&lt;br /&gt;   at System.ServiceModel.Security.SecurityUtils.GetCertificateFromStore(StoreName storeName, StoreLocation storeLocation, X509FindType findType, Object findValue, EndpointAddress target)&lt;br /&gt;   at System.ServiceModel.Security.X509CertificateInitiatorClientCredential.SetCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, Object findValue)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.ApplyClientCertificate(ClientCredentials clientCredentials)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.CreateChannelFactory[TChannel](IBaseMessage bizTalkMessage)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.InitializeValues(IBaseMessage message)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2..ctor(IBaseMessage message, WcfTransmitter`2 transmitter)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfTransmitter`2.GetClientFromCache(String spid, IBaseMessage message)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfAsyncBatch`2.BatchWorker(List`1 messages)&amp;quot;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For more information, see Help and Support Center at &lt;a href=&quot;http://go.microsoft.com/fwlink/events.asp.&quot;&gt;http:&lt;span class=&quot;rem&quot;&gt;//go.microsoft.com/fwlink/events.asp.&lt;/span&gt;&lt;br /&gt;&lt;/a&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;This error is because your client certificate is stored in your cert store, but not the cert store used by the biztalk host instance. Look at the step above showing how to run mmc as another user to fix this problem.&lt;/p&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;The adapter failed to transmit message going to send port &lt;span class=&quot;str&quot;&gt;&amp;quot;SendPort1&amp;quot;&lt;/span&gt; with URL &lt;span class=&quot;str&quot;&gt;&amp;quot;https://ServerName/TestWebserviceCommunication/TestWebserviceCommunication_ProcessMessage_SendAndRecieve.svc&amp;quot;&lt;/span&gt;. It will be retransmitted after the retry interval specified &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; Send Port. Details:&lt;span class=&quot;str&quot;&gt;&amp;quot;System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme &#39;Anonymous&#39;. ---&amp;gt; System.Net.WebException: The remote server returned an error: (403) Forbidden.&lt;br /&gt;   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)&lt;br /&gt;   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)&lt;br /&gt;   --- End of inner exception stack trace ---&lt;br /&gt;&lt;br /&gt;Server stack trace: &lt;br /&gt;   at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)&lt;br /&gt;   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)&lt;br /&gt;   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)&lt;br /&gt;   at System.ServiceModel.Channels.ServiceChannel.EndRequest(IAsyncResult result)&lt;br /&gt;&lt;br /&gt;Exception rethrown at [0]: &lt;br /&gt;   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)&lt;br /&gt;   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp;amp; msgData, Int32 type)&lt;br /&gt;   at System.ServiceModel.Channels.IRequestChannel.EndRequest(IAsyncResult result)&lt;br /&gt;   at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.RequestCallback(IAsyncResult result)&amp;quot;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For more information, see Help and Support Center at &lt;a href=&quot;http://go.microsoft.com/fwlink/events.asp.&quot;&gt;http:&lt;span class=&quot;rem&quot;&gt;//go.microsoft.com/fwlink/events.asp.&lt;/span&gt;&lt;br /&gt;&lt;/a&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;This error is because the service you have used was not trusted on the Server 2, ensure you have the correct client certificate selected in IIS.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/4971608883203865280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=4971608883203865280&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4971608883203865280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4971608883203865280'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2009/03/securing-anonymous-web-services-with.html' title='Securing Anonymous web services with Certificates'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_XNLFf_IbM28/Scu_siH0TnI/AAAAAAAAAbg/7zrQEsB7eU4/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-2679037729418936180</id><published>2009-03-15T22:27:00.001+00:00</published><updated>2009-03-15T22:30:23.286+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sql"/><title type='text'>Shrink a transaction log without doing a backup</title><content type='html'>&lt;p&gt;If you use Microsoft SQL 2005 (or 2000, and probably 2008) then Sometimes you just have to shrink the transaction log in a hurry especially if you get this error:-&lt;/p&gt; &lt;pre&gt;The transaction log for database &#39;DB NAME&#39; is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I can never remember the command to truncate the log before you can use the inbuilt tools to shrink it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In case you have the same problem here is the command:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;BACKUP LOG &lt;strong&gt;[DBNAME] &lt;/strong&gt;WITH Truncate_only&lt;/p&gt;&lt;br /&gt;&lt;p&gt;you should then be able to shrink the log without issue&lt;/p&gt;&lt;br /&gt;&lt;p&gt;P.S. There are reasons why you wouldn&#39;t want to do this (mainly around data recovery) so only do this on a test/dev environment.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Thanks&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ross&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/2679037729418936180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=2679037729418936180&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/2679037729418936180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/2679037729418936180'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2009/03/shrink-transaction-log-without-doing.html' title='Shrink a transaction log without doing a backup'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-4387697781592911256</id><published>2008-11-07T21:20:00.001+00:00</published><updated>2008-11-07T21:20:49.444+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google"/><category scheme="http://www.blogger.com/atom/ns#" term="Mesh"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft"/><category scheme="http://www.blogger.com/atom/ns#" term="Tips"/><category scheme="http://www.blogger.com/atom/ns#" term="Voip"/><title type='text'>Useful Tools</title><content type='html'>&lt;p&gt;Here are my five most useful tools&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt; &lt;a href=&quot;https://www.mesh.com/Welcome/Default.aspx&quot; target=&quot;_blank&quot;&gt;Live Mesh&lt;/a&gt;  &lt;p&gt;A great tool that you probably all know about. Lets you keep files and folders sync&#39;d across platforms (PC, Mac and smartphone at the moment). What I love most about mesh is the direction its heading, the sync bit is pretty cool (but &lt;a href=&quot;https://www.foldershare.com/&quot; target=&quot;_blank&quot;&gt;foldershare&lt;/a&gt; was sorta doing that anyway) as &lt;a href=&quot;http://blogs.technet.com/james/archive/2008/11/05/the-types-of-devices-in-live-mesh.aspx&quot; target=&quot;_blank&quot;&gt;James&lt;/a&gt; blog shows there will be four types of &#39;things&#39; which can interact with the mesh.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Creators &lt;/strong&gt;- These are things like digital cameras (even standard digital cameras using eye-fi could use this! how cool).&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Consumers &lt;/strong&gt;- devices like mp3 players and digital picture frames&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Rich end points&lt;/strong&gt; - Pcs and Macs are the main things here, but may also include printers as shown below - this I REALLY like!&lt;a href=&quot;http://lh5.ggpht.com/_XNLFf_IbM28/SRSxJx3x1zI/AAAAAAAAAXk/A2pkQXyJM4Q/s1600-h/Devices_34E10B8F%5B2%5D.jpg&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;156&quot; alt=&quot;Devices_34E10B8F&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/SRSxKo1xMoI/AAAAAAAAAXo/NpXYiq9J-l8/Devices_34E10B8F_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Processors&lt;/strong&gt; - These are more applications that run on the mesh, things like backup to another cloud app.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;You can watch the recent PDC talk here: &lt;a title=&quot;http://channel9.msdn.com/pdc2008/BB35/&quot; href=&quot;http://channel9.msdn.com/pdc2008/BB35/&quot;&gt;http://channel9.msdn.com/pdc2008/BB35/&lt;/a&gt; on it.&lt;/p&gt;  &lt;p&gt;You can also use this to remotely control your pcs from anywhere - its great as it traverses firewalls really well, much more secure than opening your pc remote desktop port to the world!&lt;/p&gt;  &lt;p&gt;This is wild speculation but I wonder how long before microsoft&#39;s Office Live (&lt;a href=&quot;http://www.liveside.net/main/archive/2008/10/31/office-in-the-cloud.aspx&quot;&gt;http://www.liveside.net/main/archive/2008/10/31/office-in-the-cloud.aspx&lt;/a&gt;) will be integrated into your mesh live desktop, and you could print to your home printer which is also in your mesh... very exciting Im sure you will agree!&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.idrive.com/&quot; target=&quot;_blank&quot;&gt;IDrive&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I love this tool. It is essentially an online backup tool which just works. You get 2GB for free or 150gb for $50 (annoyingly the set up recurring billing, and they didn&#39;t email me to remind me it would be coming out - even though they swear they did!). The backup and restore speeds are pretty decent, and the &amp;quot;continues backup&amp;quot; mode is a life saver - the first time you recover a file you deleted by accident you know it was worth the &amp;#163;30 ish quid!&lt;/p&gt;  &lt;p&gt;IDrive also supports a history mode allowing you to roll back to a previously version - very handy (and this also doesnt come out of your space allowance). Im very impressed with the security, and cant recommend this tool enough!&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.acronis.co.uk/homecomputing/products/trueimage/&quot; target=&quot;_blank&quot;&gt;Acronis True image&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This tool is similar to &lt;a href=&quot;http://shop.symantecstore.com/store/symnahho/en_US/DisplayProductDetailsPage/ThemeID.106300/productID.90124600&quot; target=&quot;_blank&quot;&gt;N&lt;/a&gt;&lt;a href=&quot;http://shop.symantecstore.com/store/symnahho/en_US/DisplayProductDetailsPage/ThemeID.106300/productID.90124600&quot; target=&quot;_blank&quot;&gt;orton ghost&lt;/a&gt; but a lot more user friendly and cheap! For those who dont know Norton Ghost this allows you to take and restore an image of your pc. If you do this once a month your machine will run very quick.&lt;/p&gt;  &lt;p&gt;This help prevent issues with activating software multiple times (starting to become more essential with the DRM included in just about everything).&lt;/p&gt;  &lt;p&gt;If you use this with Live mesh then after you restore your pc, live mesh will automatically sync your latest files to your pc from the cloud - ideal!&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.google.com/reader/&quot; target=&quot;_blank&quot;&gt;Google Reader&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Keep yourself up to date with all your favourite web sites everywhere you go (you can read it on your mobile to!)&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.mysipswitch.com/&quot; target=&quot;_blank&quot;&gt;My Sip Switch&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Im just starting to get into using VOIP at home, and I have loads to learn still, but My Sip Switch is proving to be a very good starting place. I aim to go into a lot more detail soon, but currently Im able to use my sip switch for the following setup:-&lt;/p&gt;  &lt;p&gt;I have two numbers from &lt;a href=&quot;http://www.sipgate.co.uk/user/index.php&quot; target=&quot;_blank&quot;&gt;Sipgate&lt;/a&gt;, My Sip Switch is registered with both of them. One of the numbers (my personal number) will ring the house phone automatically, the second number will only ring the house phone during allowed hours(I will use this number for companies I dont trust!). &lt;/p&gt;  &lt;p&gt;Sipgate Also provides a voicemail service, which get email to you. I am going to use the following tool to be alerted when I get an email:-&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/SRSxLCXb0OI/AAAAAAAAAXs/Y_TQN1-6HtY/s1600-h/usbwebmailnotifier%5B2%5D.jpg&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;185&quot; alt=&quot;usbwebmailnotifier&quot; src=&quot;http://lh4.ggpht.com/_XNLFf_IbM28/SRSxLyiAalI/AAAAAAAAAXw/QiPlFY8kwZE/usbwebmailnotifier_thumb.jpg?imgmax=800&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;maybe a bit tacky, but its very useful to know when you have an email!&lt;/p&gt;  &lt;p&gt;My sip gate also allows you to notify of calls via Google Talk, so I can tell when the house phone has called (and who called) when Im at work!&lt;/p&gt;  &lt;p&gt;Using &lt;a href=&quot;http://www.fring.com/&quot; target=&quot;_blank&quot;&gt;Fring&lt;/a&gt; I can also receive and make the voip calls via my smartphone, and &lt;a href=&quot;http://www.phonerlite.de/index_en.htm&quot; target=&quot;_blank&quot;&gt;Phonerlite&lt;/a&gt; to get the calls via my PC. For my home Im looking at a few different possible solutions for my home phone including a &lt;a href=&quot;http://www.blueface.ie/help/specifications.aspx?section=ata&amp;amp;item=spa3102&quot; target=&quot;_blank&quot;&gt;SPA3102&lt;/a&gt; and a SPA1001. Both cost under &amp;#163;50.&lt;/p&gt;  &lt;p&gt;Still havent quite decided how Im going to use for outbound calls, but the great thing is about My Sip Switch is that you are not tied into a particular provider. You can pick which provider you use for which calls, whether you sent your Caller ID or not, and implement redundancy (if one provider fails to call out then you can fail over to another).&lt;/p&gt;  &lt;p&gt;Finally you dont need to worry about emergency calls anymore, Sipgate allows you to make 999 calls after you set a home location.&lt;/p&gt;  &lt;p&gt;Hope you find some of these tools useful - if you do let me know!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/4387697781592911256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=4387697781592911256&amp;isPopup=true' title='83 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4387697781592911256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4387697781592911256'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/11/useful-tools.html' title='Useful Tools'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_XNLFf_IbM28/SRSxKo1xMoI/AAAAAAAAAXo/NpXYiq9J-l8/s72-c/Devices_34E10B8F_thumb.jpg?imgmax=800" height="72" width="72"/><thr:total>83</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8489764527791958010</id><published>2008-09-11T21:39:00.002+01:00</published><updated>2008-09-11T21:40:20.407+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Book Review"/><title type='text'>Patterns of Enterprise Application Architecture</title><content type='html'>&lt;p&gt;I have just started reading this book and was fascinated. What I loved most about was that I could start identifying patterns I was already using - just didn&#39;t know what they were called.&lt;/p&gt;  &lt;p&gt;The book starts of as a conversation about the different types of patterns (but always gives a page number where you can get more information) as you get towards the end of the book each pattern is discussed in much more detail (including examples in mostly Java and sometimes .net)&lt;/p&gt;  &lt;p&gt;Unfortunately Jave appears to be Martin Fowlers language of choice - the Table Data Gateway pattern has this bit of code:-&lt;/p&gt;  &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; LoadWhere(String whereClause){&lt;br /&gt;   String commandString=&lt;br /&gt;       String.Format(&quot;select * from {0} &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; {1}&quot;, TableName,WhereClause);&lt;br /&gt;   Holder.FillData(commandString, TableName);&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now I suspect most people reading this will spot the issue with the above instantly, but if not read up on SQL injection!!! (if you are unsure how devastating a sql injection attack can be then watch this video from TechEd - scary! &lt;a title=&quot;http://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=989&quot; href=&quot;http://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=989&quot;&gt;http://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=989&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Perhaps I&#39;m being picky, this is definitely only sample code - but it worries me how many people might just use this code and not notice the potential issue.&lt;/p&gt;&lt;p&gt;Anyway - the book is very good and I do recommend reading it - as Martin Fowler him self says &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&quot;Since patterns are common solutions to recurring problems, there&#39;s a good chance that you have already come across some of them... I&#39;m not claiming to present anything new in this book. Indeed, I claim the opposite, this is a book of (for our industry) old ideas.... An important part of patterns is trying to build a common vocabulary, so you can say that this class is a Remote Facade and other designers will know what you mean&quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The common vocabulary is exactly what I have found most useful about this book.&lt;/p&gt;&lt;p&gt;You can find the book on amazon here:&lt;/p&gt;&lt;p&gt;&lt;a title=&quot;http://www.amazon.co.uk/gp/product/0321150775?ie=UTF8&amp;amp;tag=develodiarie-21&amp;amp;linkCode=as2&amp;amp;camp=1634&amp;amp;creative=6738&amp;amp;creativeASIN=0321150775&quot; href=&quot;http://tinyurl.com/3ntvlm&quot;&gt;http://tinyurl.com/3ntvlm&lt;/a&gt; (ISBN: 0-32101274200)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8489764527791958010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8489764527791958010&amp;isPopup=true' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8489764527791958010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8489764527791958010'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/09/patterns-of-enterprise-application_11.html' title='Patterns of Enterprise Application Architecture'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-2250092522341394888</id><published>2008-09-05T10:17:00.001+01:00</published><updated>2008-09-05T10:17:14.452+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net 2"/><category scheme="http://www.blogger.com/atom/ns#" term=".net 3"/><category scheme="http://www.blogger.com/atom/ns#" term=".net 3.5"/><category scheme="http://www.blogger.com/atom/ns#" term="asp.net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>Getting ASP.NET menus to work with Chrome</title><content type='html'>&lt;p&gt;The asp.net menu does a check to see if the browser the client uses can support JavaScript or not. But the check is not a very good one!&lt;/p&gt;  &lt;p&gt;You can force the menu to work by overwrite the Page_PreInit method on the page and telling the page that the client target is a modern “uplevel” browser:-&lt;/p&gt;  &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Page_PreInit(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; sender, EventArgs e) &lt;br /&gt;{ &lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (Page.Request.ServerVariables[&lt;span class=&quot;str&quot;&gt;&amp;quot;http_user_agent&amp;quot;&lt;/span&gt;].ToLower().Contains(&lt;span class=&quot;str&quot;&gt;&amp;quot;safari&amp;quot;&lt;/span&gt;)) &lt;br /&gt;    { &lt;br /&gt;        Page.ClientTarget = &lt;span class=&quot;str&quot;&gt;&amp;quot;uplevel&amp;quot;&lt;/span&gt;; &lt;br /&gt;    }&lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Please note that you have to do this in the page class file, and not in the master page class file. Obviously this means you have to do it for every page – which is not ideal.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To get round this limitation simply make a class which inherits from System.Web.UI.Page, and change all your pages to inherit from this class instead (a find and replace is ideal here!).&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/2250092522341394888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=2250092522341394888&amp;isPopup=true' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/2250092522341394888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/2250092522341394888'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/09/getting-aspnet-menus-to-work-with.html' title='Getting ASP.NET menus to work with Chrome'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-3817987690648881546</id><published>2008-06-26T13:26:00.001+01:00</published><updated>2008-06-26T13:26:02.813+01:00</updated><title type='text'>RegisterDataItem can only be called during an async postback Error</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;I received the above error whilst using a ajax popup extender. Originally the popup extender was within an update panel and worked fine, the second I removed the update panel I started to get the issue.&lt;/p&gt;  &lt;p&gt;The problem turned out to be this line:-&lt;/p&gt;  &lt;p&gt;PopupStatusImage.Cancel();&lt;/p&gt;  &lt;p&gt;which basically tells the popup extender to hide. You can only call .Cancel() or .Commit() if your popup extender is within an update panel!&lt;/p&gt;  &lt;p&gt;You can simply check the Script manager to see if its a partial post back if you need to keep the cancel in for some pages etc.&lt;/p&gt;  &lt;p&gt;Hope this helps someone.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/3817987690648881546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=3817987690648881546&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/3817987690648881546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/3817987690648881546'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/06/registerdataitem-can-only-be-called.html' title='RegisterDataItem can only be called during an async postback Error'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-7512526510347162088</id><published>2008-06-19T14:56:00.001+01:00</published><updated>2008-06-19T14:56:06.121+01:00</updated><title type='text'>Learn a new Language</title><content type='html'>&lt;p&gt;I started coding in Java at uni about 4 years ago and since then I have been very Microsoft centric. Recently I have been reading Chris Dalbys blog (&lt;a title=&quot;http://www.yellowpark.net/cdalby/&quot; href=&quot;http://www.yellowpark.net/cdalby/&quot;&gt;http://www.yellowpark.net/cdalby/&lt;/a&gt;) and bought my self a current cost meter, and am very very tempted to get a SLUG.&lt;/p&gt;  &lt;p&gt;However I dont know Linux and really cant code in anything other than C#. So should I learn another language? If so which one!&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Java: Know a bit but haven&#39;t touched in in nearly 4 years.&lt;/li&gt;    &lt;li&gt;PHP: Again learned a bit at uni but not in any depth&lt;/li&gt;    &lt;li&gt;C++: Did about 10 minutes at uni of this! maybe something to learn!&lt;/li&gt;    &lt;li&gt;Ruby: Quite liked the idea of this dynamic language but was not totally sold on it!&lt;/li&gt;    &lt;li&gt;Python: No nothing about python other than its a scripting language!&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Last year I had a very interesting conversation with Dave Verner about Ruby on Rails and he said I should aim to learn a new language every year - at the time I thought he was a bit nuts, and he probably thought I was a lost cause - but I can see sense in what he was saying now!&lt;/p&gt;  &lt;p&gt;I suspect Im going to try and learn a bit more about Linux so hopefully a language which will run happily in Java makes sense (though Im pretty sure all the above run happily under Linux).&lt;/p&gt;  &lt;p&gt;Any suggestions??&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/7512526510347162088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=7512526510347162088&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7512526510347162088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7512526510347162088'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/06/learn-new-language.html' title='Learn a new Language'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-7406548056836157541</id><published>2008-06-13T23:53:00.001+01:00</published><updated>2008-06-13T23:53:56.471+01:00</updated><title type='text'>Geek Test</title><content type='html'>&lt;p&gt;If you find this funny, you are a geek!&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/ross.dargan/SFL6gD5Y8nI/AAAAAAAAARA/vR7wXaqJehg/s1600-h/n612611128_82830_1666%5B4%5D.jpg&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; border=&quot;0&quot; alt=&quot;n612611128_82830_1666&quot; src=&quot;http://lh5.ggpht.com/ross.dargan/SFL6g4F3F0I/AAAAAAAAARE/Uz0hfbAAK7E/n612611128_82830_1666_thumb%5B2%5D.jpg?imgmax=800&quot; width=&quot;423&quot; height=&quot;323&quot; /&gt;&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/7406548056836157541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=7406548056836157541&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7406548056836157541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7406548056836157541'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/06/geek-test.html' title='Geek Test'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/ross.dargan/SFL6g4F3F0I/AAAAAAAAARE/Uz0hfbAAK7E/s72-c/n612611128_82830_1666_thumb%5B2%5D.jpg?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-4158000396600369104</id><published>2008-05-10T17:00:00.001+01:00</published><updated>2008-05-10T17:00:44.747+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><title type='text'>DDD Scotland: Session Five</title><content type='html'>&lt;p&gt;Red, Green, Refactor!&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://Blog.BenHall.me.uk&quot; target=&quot;_blank&quot;&gt;Ben Hall&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Test-&amp;gt;Code -&amp;gt; Refactor&lt;/p&gt;  &lt;p&gt;Need to change your mindset&lt;/p&gt;  &lt;p&gt;Because the tests have to be written we need to stop and think about what we have to implement. This encourages better design.&lt;/p&gt;  &lt;p&gt;Code is a bit less of a black box&lt;/p&gt;  &lt;p&gt;Test code 101&lt;/p&gt;  &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;[TestFixture]&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; ObjectUnderTestTests&lt;br /&gt;{&lt;br /&gt;    [Test]&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; void MethodUnderTest_State_ExpectedBehaviour()&lt;br /&gt;    {&lt;br /&gt;        string &lt;span class=&quot;kwrd&quot;&gt;result&lt;/span&gt;=&lt;span class=&quot;kwrd&quot;&gt;Convert&lt;/span&gt;.ToString(&lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;)&lt;br /&gt;        Assert.IsTrue(tesult);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Look at the frame works &lt;a href=&quot;http://www.codeplex.com/xunit&quot; target=&quot;_blank&quot;&gt;xUnit&lt;/a&gt; and &lt;a href=&quot;http://www.mbunit.com/&quot; target=&quot;_blank&quot;&gt;MbUnit&lt;/a&gt; both contain more assertions and more attributes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;The TDD Mindset&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Huge shift in development approach&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;ALWAYS write a test before writing code &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;always run your test &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Fix failing tests as soon as possible &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;What do we test?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Everything! In isolation &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Express how we want to interact with the code &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;small, isolated section of functionality &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Single test should not be testing too much &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;What not to do!&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Showed a demo from Scott Gutheries blog showing a page load doing everything. Not possible to test.&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Showed how &lt;a href=&quot;http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET&quot; target=&quot;_blank&quot;&gt;cruise control&lt;/a&gt; can be used to automatically run all tests&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You need to have a controller set on top of the repository.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Testing in Isolation: Test Doubles&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;More flexibility for testing the application.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Dummy Objects, Stubs, Mocks, Fakes.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A Stub acts as a stand in&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Mocks are powerful normally development using a framework.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Normal: Business Logic --&amp;gt; Data Layer&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Test Dobule: Business Logic -&amp;gt; IData&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;IData -&amp;gt; DataLayer&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;IData -&amp;gt; Double (Pretends to be the data layer)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Sample:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We now want to send an email after successfully insertion.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We have an interface which implements SendInsertNotification&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The controller then takes a interface in the constructor - the test service then is used.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can get a hold of a realistic stub email service which will open port 25 etc.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Would we be creating a stub for the database? Recommended not to. But we do still want to be testing in isolation. So in the Business Layer we use the mocked data layer, and in the data layer we use the real implementation.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;These could fail for other reasons, like network going down etc.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;When testing the database you can use a tear down method which can clean the database and reseed all ids.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can also create [Setup] code which will initiate everything&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Code Coverage&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;NCover will use the profiler API to monitor what lines of code are being called an those which aren&#39;t. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Resouces&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;TDD By Exampl - Kent Beck&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href=&quot;http://www.codebetter.com&quot;&gt;www.codebetter.com&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;webblogs.asp.net/rosherove&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;RhinoMocks&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;TestDrivent.Net&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;&lt;a href=&quot;http://www.NUnit.com&quot;&gt;www.NUnit.com&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/4158000396600369104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=4158000396600369104&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4158000396600369104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/4158000396600369104'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/05/ddd-scotland-session-five.html' title='DDD Scotland: Session Five'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8283518832791569691</id><published>2008-05-10T15:40:00.001+01:00</published><updated>2008-05-10T15:40:20.541+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><category scheme="http://www.blogger.com/atom/ns#" term="Sql"/><category scheme="http://www.blogger.com/atom/ns#" term="Sql 2008"/><title type='text'>DDD Scotland: Fourth Session</title><content type='html'>&lt;p&gt;Making the leap into advanced SQL&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://sqlblogcasts.com/blogs/tonyrogerson/default.aspx&quot; target=&quot;_blank&quot;&gt;Tony Rogerson&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Sub Queries&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Sub queries (in the select statement) execute once per each row&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Derived tables&lt;/strong&gt;&lt;/p&gt;  &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; *&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; (&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; type, name &lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; sys.objects &lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; type=&lt;span class=&quot;str&quot;&gt;&#39;U&#39;&lt;/span&gt;&lt;br /&gt;) &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Syst ( type, name)&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This can be used to overcome issues with unions etc.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Nested Functions in sql 2000 causes the function to be called twice. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Logically derived tables are a virtual table. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;There are no statistics held on them. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Its self contained. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Common Table Expressions&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Can be used for recursion&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;;&lt;span class=&quot;kwrd&quot;&gt;with&lt;/span&gt; cteName (name, type, rowpos)&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; (&lt;br /&gt;     &lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; name,type, rowpos = RowNumber() &lt;span class=&quot;kwrd&quot;&gt;over&lt;/span&gt; (partition &lt;span class=&quot;kwrd&quot;&gt;by&lt;/span&gt; type &lt;span class=&quot;kwrd&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;by&lt;/span&gt; name)&lt;br /&gt;     &lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; sys.objects&lt;br /&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Unlike derived tables this does let you self join e.g.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;declare&lt;/span&gt; @HowMany &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;set&lt;/span&gt; @HowMay = 10&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;with&lt;/span&gt; loopIT(i, descr)&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;AS&lt;/span&gt; (&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; i=1, descr=&lt;span class=&quot;kwrd&quot;&gt;CAST&lt;/span&gt;(&lt;span class=&quot;str&quot;&gt;&#39;Anchor&#39;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;varchar&lt;/span&gt;(100))&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;all&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; i=i+1, descr = &lt;span class=&quot;kwrd&quot;&gt;CAST&lt;/span&gt;(&lt;span class=&quot;str&quot;&gt;&#39;recuresed&#39;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;varchar&lt;/span&gt;(100))&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; LOOPIT&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;Where&lt;/span&gt; i&amp;lt;@howmany&lt;br /&gt;    )&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; i, descr&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; LoopID&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Like derived table there are no stats, and they are expanded - but they do allow self join unlike derived tables. By default you can only recurse 100 times - you can extend this with MAXRECURSION.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;strong&gt;Temporary tables/Table Variables&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;#Tables hold stats - you can tell it to refresh them and then the plan is more accurate.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Table Variables are only meant for &amp;lt; 1000 rows - so you get no stats but you do get the option to recompile - option (recompile). However it is not very accurate&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Sql plan uses the order of the column to compute selects not the most optimal index as it would use on a #table.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Table variable is not in memory, even local variables are stored on disk.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Hash tables do cause a compile lock so this causes an overhead, where as table variables dont - so they are better!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Cumulative Totals&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can use sub queries for this&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; *,&lt;br /&gt;tytd = (&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;sum&lt;/span&gt;(accounts) &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; xxx),&lt;br /&gt;mytd = (&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;sum&lt;/span&gt;(accounts) &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; xxx)&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; accounts a&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The one pass approach uses the case expression&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;select&lt;/span&gt; *,&lt;br /&gt;tytp = &lt;span class=&quot;kwrd&quot;&gt;sum&lt;/span&gt;(&lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;when&lt;/span&gt; xxx &lt;span class=&quot;kwrd&quot;&gt;then&lt;/span&gt; amount &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; 0),&lt;br /&gt;mytp = &lt;span class=&quot;kwrd&quot;&gt;sum&lt;/span&gt;(&lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;when&lt;/span&gt; xxx &lt;span class=&quot;kwrd&quot;&gt;then&lt;/span&gt; amount &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; 0)&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;from&lt;/span&gt; accounts a&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can use pivots tables also, and CTE tables&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;u&gt;Performance&lt;/u&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You shouldn&#39;t use Duration - it is has a high duration but a low number of reads that means there is a problem somewhere. Reads, CPU are the two columns you should read. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Sub query = 6.5k reads &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;1 pass = 417 reads &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;union all = 1200 reads &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;and the pivot 1201 reads &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Running Totals&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;CTE can do it by adding a row number, then self join look for the previous row and sum as you go along. However the query gets copied into each query + it doesnt filter rows correctly so this costs a lot in reads&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Better approach is to copy it into a temporary table, index it then make your CTE read from the temporary table. goes from 20k reads to 7k.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8283518832791569691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8283518832791569691&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8283518832791569691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8283518832791569691'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/05/ddd-scotland-fourth-session.html' title='DDD Scotland: Fourth Session'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8340068632014186413</id><published>2008-05-10T13:05:00.001+01:00</published><updated>2008-05-10T13:05:25.833+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><category scheme="http://www.blogger.com/atom/ns#" term="Sql 2008"/><category scheme="http://www.blogger.com/atom/ns#" term="SSIS"/><title type='text'>DDD Scotland: Third Session</title><content type='html'>&lt;p&gt;Integration Service in Sql 2008&lt;/p&gt;  &lt;p&gt;Allan Mitchell &lt;a href=&quot;http://www.SQLDTS.com\&quot;&gt;www.SQLDTS.com\&lt;/a&gt; &lt;a href=&quot;http://www.SQLIS.com&quot;&gt;www.SQLIS.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Behind the scenes: Threading&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Multicast Transform generates n copies of the input. This is the same in 2008 but all output are on the same execution Path instead of the same thread.&lt;/p&gt;  &lt;p&gt;A raw file means that IIS doesn&#39;t have to translate information - this means that its ideal for staging data.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;To work around issues with SSIS 2005 you use the union all component. This works because the union all works asynchronously. This causes another execution tree (Another thread). This is not needed in 2008.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Pipeline Limiter&lt;/p&gt;  &lt;p&gt;This doesnt sound good because we are moving data! Limiter exists in 2005 so its not going to be slower in 2008 - just you didnt know about it. In 2008 they tell you about it so you now get performance counters.&lt;/p&gt;  &lt;p&gt;Why would I want to restrict the pipeline?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Date = buffer = memory. &lt;/li&gt;    &lt;li&gt;Memory is reused when the buffer terminates&lt;/li&gt;    &lt;li&gt;push back from a component = no reuse of memory = run out of memory!&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Dont use select * because it will need to allocate memory in the buffer for something we wont use.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;To capture these event in the Feb CTP you need to check the log messages for an attribute starting with &amp;quot;The Component%&amp;quot; Expect this to change tho&lt;/p&gt;  &lt;p&gt;You can now use C# in the script component to write/manipulate data.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lookup Component&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Caching Options&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Full: Before its used everything gets cached - Slow startup&lt;/li&gt;    &lt;li&gt;Partial: Lookup component will try for a match in the cache first, then check the file.&lt;/li&gt;    &lt;li&gt;None - The last query is cached but that it. Try to order your data. This is useful for volatile data.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Full cache is fasted but might take longest to cache, and a large amount of memory.&lt;/p&gt;  &lt;p&gt;In 2005 these cannot be passed around - so if you want to loop through a directory then it will be cached for every file! This is also not transferable.&lt;/p&gt;  &lt;p&gt;In 2008 there is now something called a Cache Transform. This can be used as a destination.&lt;/p&gt;  &lt;p&gt;You can cache to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A file - Its a Raw File&lt;/li&gt;    &lt;li&gt;In Memory&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This allows the reference to be passed around.&lt;/p&gt;  &lt;p&gt;Because you can doesnt mean you should - by default the 2005 way is used.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Row Redirection&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;If a lookup component gets no match then by default it fails. You have to configure a redirect down the error output to ignore it if this should not be an error.&lt;/p&gt;  &lt;p&gt;Now in 2008 we have a no match output option.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Points to note:&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;Lookup transform is case sensitive when done in cache. Obviously this is not the case in SQL&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Data Profiling Task&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Profiles data in your database (can do quick setup or verbose). only SQl2000 or above can be profiled.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Side Note: If you are going to Sql server then use the OLE Connection manager or the sql connection manager&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This is fantastic for seeing how rubbish the data is.&lt;/p&gt;  &lt;p&gt;Useful for identifying distribution of values.&lt;/p&gt;  &lt;p&gt;Microsoft have provided a date profile viewer to read the xml produced by the above component. Which is really powerful - you can drill into it quite easily.&lt;/p&gt;  &lt;p&gt;This is useful for checking data sent from a provider.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Change Data Capture (CDC)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Billed as an ETL function.&lt;/p&gt;  &lt;p&gt;Gives increased efficiency - incremental extractions.&lt;/p&gt;  &lt;p&gt;You can identify changed rows and columns.&lt;/p&gt;  &lt;p&gt;Essentially transaction replication. It uses the log reader.&lt;/p&gt;  &lt;p&gt;A lot of people uses triggers - this doesnt!&lt;/p&gt;  &lt;p&gt;Use a sp called sp_cdc_enable_table with parameters to define the table you want to do the change data capture on.&lt;/p&gt;  &lt;p&gt;Supports net changes/all changes so you can decide how you need your data (and potentially save space)&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8340068632014186413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8340068632014186413&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8340068632014186413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8340068632014186413'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/05/ddd-scotland-third-session.html' title='DDD Scotland: Third Session'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-6904476750792468198</id><published>2008-05-10T11:46:00.001+01:00</published><updated>2008-05-10T11:46:04.866+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><title type='text'>DDD Scotland: Second Session</title><content type='html'>&lt;p&gt;[Apologies because my laptop blue screened and windows live writer doesn&#39;t do auto recovery:( I REALLY need a new laptop now! - everything up to abusing threads is from memory]&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a title=&quot;How to Write Crap Code in C#&quot; href=&quot;http://www.benlamb.com/downloads/talks/CrapCode.pdf&quot;&gt;How to Write Crap Code in C#&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ben Lamb &lt;a href=&quot;http://www.benlamb.com&quot;&gt;www.benlamb.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Started the demo by showing an application which analyses all off Shakespeare&#39;s books to count every word and figure out how often the words are used. Initially he runs it and it takes 2 minutes 1 second which he then explains has a sleep.timer in there set to 2 minutes&lt;/p&gt;  &lt;p&gt;Initial program: 1 second&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Abusing Exceptions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Initially he checked a dictionary to see if a word existed before updating it. This was then changed to just try and update the dictionary, and if it doest exist handle the exception to add it in.&lt;/p&gt;  &lt;p&gt;When he ran this he showed us the CPU maxing out, and performance monitor looking at the number of errors thrown a second (175000 was how many)&lt;/p&gt;  &lt;p&gt;Exception flowing: 41 seconds&lt;/p&gt;  &lt;p&gt;Ben 1 - Redmond 0&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Abusing Threads&lt;/strong&gt;    &lt;br /&gt;You can get a thread by:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Using async callbacks&lt;/li&gt;    &lt;li&gt;Threadpool&lt;/li&gt;    &lt;li&gt;manually using Thread() &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;to really screw up a program you have to use Lock() &lt;/p&gt;  &lt;p&gt;modify the program so we have one thread for each text file, and then we lock on the dictionary. &lt;/p&gt;  &lt;p&gt;Multi Threaded analysers 1 second&lt;/p&gt;  &lt;p&gt;Ben 1- Redmond 1&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Misuse of the heap (Fun with Strings)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Value objects get stored on the stack (ints etc), reference objects get stored on the head.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Avoid Boxing/UnBoxing&lt;/li&gt;    &lt;li&gt;Use Generic classes&lt;/li&gt;    &lt;li&gt;Cache Locality&lt;/li&gt;    &lt;li&gt;Prefer code that works to fast code.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Garbage collection is designed to clean up code - it can use reference counters. This causes the counter to be locked which can cause performance problems. .net uses mark and sweep which walks through an object tree and looks and everything and object it comes across is marked because its being used. Anything not marked gets removed. Then it sweeps everything to group together memory (defraging basically).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Every time an object goes through a process like this its generation gets marked as either generation 0/1/2 - the ones which are old (gen 2) they get put to the bottom so the garbage collection doesn&#39;t worry about it too much. Pinned objects are objects which cant be moved because its unmanaged code - this confuses things a bit.&lt;/p&gt;  &lt;p&gt;Garbage collection is not deterministic - but don&#39;t bother calling it yourself you just make things worse. Plus things like the virus checker could cause more issues.&lt;/p&gt;  &lt;p&gt;Showed a normalise line which basically loops through an array of chars to check it is a letter or a space. String builder is then used to append the values together. He changes this to a string which concats itself with the char.&lt;/p&gt;  &lt;p&gt;Ben explains that he uses system.diagnostics.stopwatch to show performance details.&lt;/p&gt;  &lt;p&gt;Consider putting timer metrics into apps so you can track down issues.&lt;/p&gt;  &lt;p&gt;There are some counters showing garbage collection information. % of time in GC is really what you are after. any more in 10% then you have issues.&lt;/p&gt;  &lt;p&gt;String concatenation takes: 1 minute 24 seconds.&lt;/p&gt;  &lt;p&gt;Ben 2 - Redmond 1.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/6904476750792468198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=6904476750792468198&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/6904476750792468198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/6904476750792468198'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/05/ddd-scotland-second-session.html' title='DDD Scotland: Second Session'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-1436130248424436118</id><published>2008-05-10T10:52:00.001+01:00</published><updated>2008-05-10T13:32:29.674+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><category scheme="http://www.blogger.com/atom/ns#" term="WCF"/><title type='text'>DDD Scotland: First Session</title><content type='html'>&lt;p&gt;Web Services: We dont need no stinking web server&lt;/p&gt;  &lt;p&gt;Barry Dorrans &lt;a title=&quot;http://idunno.org/&quot; href=&quot;http://idunno.org/&quot;&gt;http://idunno.org/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Agenda&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What is WCF &lt;/li&gt;    &lt;li&gt;WCF Vs Remoting &lt;/li&gt;    &lt;li&gt;SOA, Services, Interfaces &lt;/li&gt;    &lt;li&gt;Proving it &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Remoting is going, WCF is an open standard (WS*) so much better, Also transport neutral so we can quickly switch from HTTP to TCP/MSMQ etc.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://www.codeproject.com/script/Membership/Profiles.aspx?mid=24570&quot; target=&quot;_blank&quot;&gt;Roman Kiss&lt;/a&gt; has a &lt;a href=&quot;http://www.codeproject.com/KB/WCF/NullTransportForWCF.aspx&quot; target=&quot;_blank&quot;&gt;null transport&lt;/a&gt; module which allows you to just communicate in memory&lt;/p&gt;  &lt;p&gt;WCF Vs Remoting&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;WCF requires less permissions, runs in medium trust (mostly). &lt;/li&gt;    &lt;li&gt;Easier versioning with WCF. &lt;/li&gt;    &lt;li&gt;Two way communications (callback contracts) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;SOA approach. Write the contracts first.&lt;/p&gt;  &lt;p&gt;ABCs of WCF: Address (where to talk), Binding (how to talk), Contract (what we are talking about)&lt;/p&gt;  &lt;p&gt;A server endpoint is constructed of Address binding Channel&lt;/p&gt;  &lt;p&gt;A service can have multiple bindings - defines the shape of the service and the security.&lt;/p&gt;  &lt;p&gt;A contract is defined for the service, data and message - can also create one for errors etc.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;MEP: Message Exchange Protocol&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Request - Reply &lt;/li&gt;    &lt;li&gt;One Way &lt;/li&gt;    &lt;li&gt;Duplex &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Service Contracts are decorated with the attribute [Service Contract] and the methods with [Operation Contract]&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Data contracts are decorated with [DataContract] and properties/functions with [MemberContract] - this gives us control of the message body or header - but ordering allows us to create optional components or to order them.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Step by Step instructions will be published&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Create a WCF service library&lt;/p&gt;  &lt;p&gt;Visual studio 2008 includes a test client for the library project. This even lets you inspect your request/response header.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/ross.dargan/SCVwN2M_YII/AAAAAAAAAQI/pPS5aoKS7FM/1280360982_195dc4bcfb5.jpg?imgmax=800&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;340&quot; alt=&quot;1280360982_195dc4bcfb&quot; src=&quot;http://lh6.ggpht.com/ross.dargan/SCVwOWM_YJI/AAAAAAAAAQQ/BvIFqsp_9rg/1280360982_195dc4bcfb_thumb3.jpg?imgmax=800&quot; width=&quot;410&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Shows a simple?! wcf configuration file. Right clicking on it bring up the WCF configuration editor. This allows you to really easily change settings like the bindings.&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;http://lh4.ggpht.com/ross.dargan/SCVwO2M_YKI/AAAAAAAAAQY/jis_HODVGus/image_7676362bbca14c398e781ffe7f17eb%5B1%5D.png?imgmax=800&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;306&quot; alt=&quot;image_7676362b-bca1-4c39-8e78-1ffe7f17eb40&quot; src=&quot;http://lh4.ggpht.com/ross.dargan/SCVwP2M_YLI/AAAAAAAAAQg/pDJuuVGUwdY/image_7676362bbca14c398e781ffe7f17eb%5B2%5D.png?imgmax=800&quot; width=&quot;412&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;WCF doesn&#39;t require a webserver to host HTTP web services&lt;/p&gt;  &lt;p&gt;With windows 2008 it gets better. In XP/Vista we have to write a host if we dont use IIS with WAS we can host a service under any protocol underneath IIS.&lt;/p&gt;  &lt;p&gt;Running through a demo called Rumour. Talks about using a constant file to define the namespace.&lt;/p&gt;  &lt;p&gt;Name spaces should include a date to support versioning to prevent breaking changes&lt;/p&gt;  &lt;p&gt;showed how you can set isrequired=false but did this on an int&lt;strong&gt;&lt;em&gt;... not sure how WCF can handle a value non nullable type not being passed in?: &lt;/em&gt;Barry said that this would result in the int being set to a 0.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Barry recommends using Visual Studio 2008 because 2005 doesn&#39;t have a test harness.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What have we learned&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We need data contracts for versioning. WCF will not send items down unless members are marked as a data contract. Barry claimed that even if you mark data as serializable it wont send it down the link&lt;strong&gt;... &lt;em&gt;Im not sure this is correct as im sure I have done this... so I will chase it up&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;[LIVE DEMO]&lt;/p&gt;  &lt;p&gt;Showed the MEX endpoint exposing meta data information.&lt;/p&gt;  &lt;p&gt;To stop the service you must do:-&lt;/p&gt;  &lt;div class=&quot;csharpcode-wrapper&quot;&gt;   &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; StopService()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt;(myServiceHost.Stae == CommuncationState.Faulted)&lt;br /&gt;&lt;br /&gt;MyserviceHost.Abort();&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (myServiceHost.State!= CommincationState.Closed)&lt;br /&gt;&lt;br /&gt;MyServiceHost.Close();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The reason we need this is because you cant use the using statement. Disposing of the WCF service calls close but if it is in a faulted state then it will throw an exception.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Do try and host WCF in IIS.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Replacing ASMX - double decorate contracts what the action &amp;amp; message names, rename the service and only use basic http binding.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Demonstrated creating a service host by passing in the base address&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;AddressAccessDeniedException - the process does not have rights to the name space, so that needs to be registered... however you can just run as admin.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This command allows you to register the address:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;netsh http add urlacl url=http:\\+:8080\RumourService user=builtin\users&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This should be done at install time.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Getting service host information:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;csharpcode-wrapper&quot;&gt;&lt;br /&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;endpoint.Address&lt;br /&gt;&lt;br /&gt;endpoint.Binding.name&lt;br /&gt;&lt;br /&gt;endpoint.Contract.name&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Add service reference and discover is clever enough to check local projects (if they have an app.config file). Does this require the mex data?&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The app.config then needed to be renamed to stop an error from happening&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;[My battery ran out even after a full charge - need a new one! so had to resort to manual blogging (pen&amp;amp;paper) - apologies if if this not as accurate]&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Need to turn on error propagation on in the web.config. This then send the error message through but still sends it as a fault exception. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can declare a data context which is decorated with the fault contract which allows the correct error to be send to the client and handled.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This then marshals everything into a soap fault&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Barry then did a very quick run through of duplex working.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/1436130248424436118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=1436130248424436118&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/1436130248424436118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/1436130248424436118'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/05/ddd-scotland-first-session.html' title='DDD Scotland: First Session'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/ross.dargan/SCVwOWM_YJI/AAAAAAAAAQQ/BvIFqsp_9rg/s72-c/1280360982_195dc4bcfb_thumb3.jpg?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-7526217718273610745</id><published>2008-04-30T22:17:00.003+01:00</published><updated>2008-05-01T11:24:11.667+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="BarCamp"/><category scheme="http://www.blogger.com/atom/ns#" term="BarCampNorthEast"/><category scheme="http://www.blogger.com/atom/ns#" term="Code Works"/><category scheme="http://www.blogger.com/atom/ns#" term="Conference"/><category scheme="http://www.blogger.com/atom/ns#" term="DDD Scotland"/><category scheme="http://www.blogger.com/atom/ns#" term="Thinking Digital"/><title type='text'>NO SPECTATORS, ONLY PARTICIPANTS</title><content type='html'>&lt;p&gt;There are loads of great conferences going on in may&lt;/p&gt;&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;400&quot; border=&quot;0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;150&quot;&gt;&lt;img src=&quot;http://developerdayscotland.com/images/badges/GetReady1-small.png&quot; /&gt;&lt;br /&gt;Where: Glasgow&lt;br /&gt;How Much: Free!&lt;/td&gt;&lt;td valign=&quot;top&quot; width=&quot;246&quot;&gt;First up on Saturday the 10th of May is &lt;a href=&quot;http://developerdayscotland.com/&quot; target=&quot;_blank&quot;&gt;DDD Scotland&lt;/a&gt; (mentioned &lt;a href=&quot;http://blog.the-dargans.co.uk/2008/03/ddd-scotland-registration-open.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;). This is a free community event with some great tracks and speakers including &lt;a href=&quot;http://idunno.org/default.aspx&quot;&gt;Barry Dorrans&lt;/a&gt; (covering WCF - cant wait), &lt;a href=&quot;http://blog.colinmackay.net/&quot;&gt;Colin Angus Mackay&lt;/a&gt; and whilst I havent heard of &lt;a href=&quot;http://www.garyshort.org/&quot;&gt;Gary Short&lt;/a&gt; before he perhaps has the best Bio I have ever read (Gary Short was employed as a canoeist, but was presumed dead after disappearing under mysterious circumstances, only to reappear 5 years later. Gary had used this time to secretly re-train as a software Jedi and now plies his trade throughout the known galaxies, where he sells his skills to the highest bidder. Outside of his dog, his laptop is his best friend; inside of his dog, it&#39;s too dark to use it.)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;150&quot;&gt;&lt;img src=&quot;http://www.thinkingdigital.co.uk/z_siteimages/img_146_1200942891_-1_-1_0_scaled.jpg&quot; /&gt;&lt;br /&gt;Where: Newcastle&lt;br /&gt;How Much: £599 + VAT&lt;/td&gt;&lt;td valign=&quot;top&quot; width=&quot;246&quot;&gt;Next up is Thinking Digital run by CodeWorks on the 21st to the 23rd... not so much development  - although &lt;a title=&quot;Steve Clayton&quot; href=&quot;http://blogs.msdn.com/stevecla01&quot;&gt;Steve Clayton&lt;/a&gt; will be there talking about Microsoft new Mesh technology - even though he didn&#39;t give me an &lt;a href=&quot;http://blogs.msdn.com/stevecla01/archive/2008/04/23/live-mesh-i-have-3-invites.aspx&quot; target=&quot;_blank&quot;&gt;invite&lt;/a&gt;!&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; width=&quot;150&quot;&gt; &lt;a href=&quot;http://lh3.ggpht.com/ross.dargan/SBjh3HIi4aI/AAAAAAAAAP4/rjD72rgJrdw/s1600-h/barcamp5.png&quot;&gt;&lt;br /&gt;&lt;img style=&quot;BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px&quot; height=&quot;122&quot; alt=&quot;barcamp&quot; src=&quot;http://lh6.ggpht.com/ross.dargan/SBjh33Ii4bI/AAAAAAAAAQA/pvm3-PiRmWo/barcamp_thumb3.png?imgmax=800&quot; width=&quot;137&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Where: Newcastle&lt;br /&gt;How Much: Free*&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;*=May cost a demo/presentation &lt;/td&gt;&lt;td valign=&quot;top&quot; width=&quot;246&quot;&gt;And finally &lt;a href=&quot;http://www.barcamp.org/BarCampNorthEast&quot; target=&quot;_blank&quot;&gt;Bar Camp: North East&lt;/a&gt; straight after thinking digital on the  24th and 25th.&lt;br /&gt;&lt;p&gt;The Rules of &lt;strike&gt;Fight Club&lt;/strike&gt; Bar Camp are pretty simple, you have to take part... and that worries me a bit! At work we hold regular knowledge sharing seminars and its a great way to pass on new skills and anyone who knows me will tell you how much I love going on about some new technology - but running a demo/session outside of work is a different kettle of fish!&lt;/p&gt;&lt;p&gt;So I don&#39;t really have any idea what will be covered here, but Im really looking forward to meeting other developers from the North East!&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Looks like I am going to have a busy May!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/7526217718273610745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=7526217718273610745&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7526217718273610745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/7526217718273610745'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/04/no-spectators-only-participants.html' title='NO SPECTATORS, ONLY PARTICIPANTS'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/ross.dargan/SBjh33Ii4bI/AAAAAAAAAQA/pvm3-PiRmWo/s72-c/barcamp_thumb3.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-8191920083549879847</id><published>2008-03-17T11:32:00.001+00:00</published><updated>2008-03-17T11:32:59.149+00:00</updated><title type='text'>DDD Scotland - registration open</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://lh6.google.com/ross.dargan/R95W5ZYy6oI/AAAAAAAAAPo/j0IWxpAp3UM/GetReady1-large%5B13%5D?imgmax=800&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;244&quot; alt=&quot;GetReady1-large&quot; src=&quot;http://lh3.google.com/ross.dargan/R95W6pYy6pI/AAAAAAAAAPw/cYDX4mqSdZ8/GetReady1-large_thumb%5B7%5D?imgmax=800&quot; width=&quot;184&quot; align=&quot;right&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; This looks like its going to be a very good community event with some really interesting tracks. You can see the agenda &lt;a href=&quot;http://developerdayscotland.com/main/Agenda/tabid/68/Default.aspx&quot;&gt;here&lt;/a&gt; and sign up &lt;a href=&quot;http://developerdayscotland.com/main/DelegateRegistration/tabid/69/Default.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Really looking forward to this, just wish there where more events like this in the North East!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/8191920083549879847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=8191920083549879847&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8191920083549879847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/8191920083549879847'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/03/ddd-scotland-registration-open.html' title='DDD Scotland - registration open'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3404451797694685821.post-38986998324318508</id><published>2008-03-15T10:59:00.001+00:00</published><updated>2008-03-15T10:59:10.223+00:00</updated><title type='text'>Idea for some software</title><content type='html'>&lt;p&gt;I have just seen Will Shipley&#39;s latest Blog posting (&lt;a title=&quot;http://wilshipley.com/blog/2008/02/ted2008-part-1-gossip.html&quot; href=&quot;http://wilshipley.com/blog/2008/02/ted2008-part-1-gossip.html&quot;&gt;http://wilshipley.com/blog/2008/02/ted2008-part-1-gossip.html&lt;/a&gt;) and he says he has had his mac book stolen but he knows his MAC code, so he wants people to look out for it.&lt;/p&gt;  &lt;p&gt;Well this got me thinking - what if everyone subscribes their laptop mac code to a website, and if it goes missing they flag it as stolen. Then working with people who provide WIFI services we have a little app which basically checks the list. If a stolen mac address is spotted then the police could be notified. &lt;/p&gt;  &lt;p&gt;Just a thought - but I think this could be a really useful tool against laptop theft!&lt;/p&gt;  &lt;p&gt;Ross&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.the-dargans.co.uk/feeds/38986998324318508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3404451797694685821&amp;postID=38986998324318508&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/38986998324318508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3404451797694685821/posts/default/38986998324318508'/><link rel='alternate' type='text/html' href='http://blog.the-dargans.co.uk/2008/03/idea-for-some-software.html' title='Idea for some software'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/07911305725094254509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>