TED Open Source: How we went live with our electricity use.

TED powered electricity monitoringAs promised, below you will find our recipe for the TED, The Energy Detective hack that enabled us to publish our electricity use on the Energy Circle site, starting Earth Day. Thanks to Peter Murray for putting this together. If you take this on, good luck! Please report back to let us know how it goes.

Recipe for: ASUS WL-500g router as TED data harvester

Please note, these instructions are designed for folks comfortable hacking Linux at a fairly low level.

 

  1. Purchase an ASUS WL-500g Premium (I used v2). Here's a link at NewEgg:Asus WL-500gP. Technically you could use any device that will run Linux and has a USB port that can be plugged into your TED - we liked the small form factor and energy efficiency of the ASUS router over running a full computer for this purpose.

  2. Follow the instructions here to build and install OpenWRT Kamikaze for the ASUS. Change the root password and reboot before proceeding.

  3. Once it's up an running, log in and install and remove the following packages. This will involve editing your opkg.conf file and setting up your host with http running and serving the build modules.
    opkg remove kmod-ppp opkg remove kmod-pppoe opkg remove ppp-mod-pppoe opkg remove ppp opkg install kmod-usb-serial opkg install kmod-usb-serial-ftdi opkg install libpthread opkg install python-mini opkg install pyserial opkg install usbutils opkg install curl opkg install ntpclient
  4. Configure the wifi for client operation. Below are configurations I used to connect to a WPA protected network with a static IP address. You will need to substitute your network's IPs - or use DHCP.
    # edit /etc/config/network to configure the wifi interface config interface wifi option ifname "wl0" option proto static option ipaddr <IP ADDRESS> option netmask 255.255.255.0 option gateway <GW ADDRESS> option dns <DNS SERVER ADDRESS> # edit /etc/config/wireless appropriately for the local network --------------------------------- config 'wifi-device' 'wl0' option 'type' 'broadcom' option 'channel' '6' option 'disabled' '0' config 'wifi-iface' option 'device' 'wl0' option 'network' 'wifi' option 'mode' 'sta' option 'ssid' '' option 'encryption' '' option 'key' '' ---------------------------- wifi up # install nas start script /etc/init.d/nas start ln -s /etc/init.d/nas /etc/rc.d/S55nas
    YMMV with these configurations - consult the www.openwrt.org site for loads of forum posts etc on configuring OpenWRT as a client in various situations.

  5. Manually install the termios.so library from the full python build. This is required to run the python serial interface (pyserial) to access TED.
    scp <USER>@<YOUR_HOST>:/<path_to_kamikaze_build_of>/termios.so \ /usr/lib/python2.6/lib-dynload
  6. Plug in TED USB cable to router. You should shortly see dmesg output like this:
    usb.c: registered new driver serial usbserial.c: USB Serial support registered for Generic usbserial.c: USB Serial Driver core v1.4 usbserial.c: USB Serial support registered for FTDI SIO usbserial.c: USB Serial support registered for FTDI 8U232AM Compatible usbserial.c: USB Serial support registered for FTDI FT232BM Compatible usbserial.c: FTDI FT232BM Compatible converter detected usbserial.c: FTDI FT232BM Compatible converter now attached to ttyUSB0\ (or usb/tts/0 for devfs) usbserial.c: USB Serial support registered for USB-UIRT Infrared\ Tranceiver usbserial.c: USB Serial support registered for Home-Electronics TIRA-1\ IR Transceiver ftdi_sio.c: v1.3.5:USB FTDI Serial Converters Driver
    And you should have the device node /dev/usb/tts/0 available.

  7. Download the ted.py file originally written by Micah Dowty:
    wget http://www.bananabend.net/energy_detective/python/ted_orig.py
  8. Run with
    python ted_orig.py /dev/usb/tts/0
    and you should get output from your TED.

  9. At this point, you can modify the python script to do whatever you like with the output from TED. We modified the ted_orig.py to dump the results every second into a file in the OpenWRT's ramdisk. The modified version of the TED python script is here. We started this script with an init.d entry:
    #!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org START=50 start () { /usr/bin/python /root/ted2.py /dev/usb/tts/0 & } stop() { killall -9 python }
  10. We then created a quick shell script that used curl to post the output to a PHP script on our server using curl. This is fired from cron once per minute.
    #!/bin/sh if [ -f /tmp/ted ]; then VALUE=`cat /tmp/ted` echo ${VALUE} > /tmp/post.out /usr/bin/curl --max-time 15 <SERVER_URL>?${VALUE} >> /tmp/post.out 2>&1 else echo 'skipped' > /tmp/post.out fi
  11. The server-side php script that SERVER_URL pointed to looks like this:
    <?php # # Insert code to extablish mysql connection to database # $housecode = $_GET{'house_code'}; $kw_rate = $_GET{'kw_rate'}; $volts = $_GET{'volts'}; $kw = $_GET{'kw'}; if($kw && $housecode) { $insert = "insert into ted_data (housecode, ts, value) values ('" . $housecode . "', '" . date("Y-m-d H:i:00") . "', " . $kw . ")"; mysql_query($insert); $err = mysql_error(); if($err) { echo "ERROR: " . $err; } else { echo "OK"; } } else { echo "ERROR: Bad input"; } ?>
  12. The schema for the database looks like this
    CREATE TABLE IF NOT EXISTS `ted_data` ( `ts` datetime default '0000-00-00 00:00:00', `value` double NOT NULL, `title` varchar(256) default NULL, `annotation` text, `housecode` varchar(5) NOT NULL );
  13. We then used the PHP Google Datasource adapter found here to establish our Google Datasource.
    <?php ob_start("ob_gzhandler"); error_reporting (E_ALL ^ E_NOTICE); require_once 'MC/Google/Visualization.php'; $db = new PDO('mysql:host=' . $DBHost . ';dbname=' . $DBase, $User, $Password); $vis = new MC_Google_Visualization($db, 'mysql'); $vis->addEntity('ted_data', array( 'table' => 'ted_data', 'fields' => array( 'timestamp' => array('field' => 'ts', 'type' => 'datetime'), 'kW' => array('field' => 'value', 'type' => 'number'), 'title' => array('field' => 'title', 'type' => 'text'), 'annotation' => array('field' => 'annotation', 'type' => 'text'), ), 'where' => 'ts > date_sub(now(), interval 72 HOUR)' ) ); $vis->setDefaultEntity('ted_data'); $vis->handleRequest(); ?>
  14. And, finally, used Google's Annotated Timeline widget to render the graph. We used some JS to modify the layout of the timeline widget to integrate with the EnergyCircle look and feel - for clarity that code is not included here...
    <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load("visualization", "1", {packages:["annotatedtimeline"]}); google.loader.writeLoadTag("css", "ted.css"); google.setOnLoadCallback(drawChart); var query; function reload() { query.send(callback); } function isIE() { return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent); } function callback(result) { if(result.isError()) { alert(result); } else { chart.draw(result.getDataTable(), {displayAnnotations: true, allowHtml: true}); } setTimeout("reload();", 60 * 5 * 1000); }; function drawChart() { query = new google.visualization.Query('/ted_query.php'); query.setQuery('select timestamp, kW, title, annotation'); var div = document.getElementById('chart_div'); chart = new google.visualization.AnnotatedTimeLine(div); query.send(callback); } </script> <div style="height:825px" id='chart_div'>Loading...</div>

Please let us know if this recipe is helpful and feel free to post questions, errors, or omissions here or email info@energycircle.com.

Updated May 29, 2009 @ 13:40 for formatting and tiny content changes - more info coming!

Updated May 29, 2009 @ 14:30 to include server-side code

 

TED powered electricity monitoringAs promised, below you will find our recipe for the TED, The Energy Detective hack that enabled us to publish our electricity use on the Energy Circle site, starting Earth Day. Thanks to Peter Murray for putting this together. If you take this on, good luck! Please report back to let us know how it goes.

Recipe for: ASUS WL-500g router as TED data harvester

Please note, these instructions are designed for folks comfortable hacking Linux at a fairly low level.

 

  1. Purchase an ASUS WL-500g Premium (I used v2). Here's a link at NewEgg:Asus WL-500gP. Technically you could use any device that will run Linux and has a USB port that can be plugged into your TED - we liked the small form factor and energy efficiency of the ASUS router over running a full computer for this purpose.

  2. Follow the instructions here to build and install OpenWRT Kamikaze for the ASUS. Change the root password and reboot before proceeding.

  3. Once it's up an running, log in and install and remove the following packages. This will involve editing your opkg.conf file and setting up your host with http running and serving the build modules.
    opkg remove kmod-ppp opkg remove kmod-pppoe opkg remove ppp-mod-pppoe opkg remove ppp opkg install kmod-usb-serial opkg install kmod-usb-serial-ftdi opkg install libpthread opkg install python-mini opkg install pyserial opkg install usbutils opkg install curl opkg install ntpclient
  4. Configure the wifi for client operation. Below are configurations I used to connect to a WPA protected network with a static IP address. You will need to substitute your network's IPs - or use DHCP.
    # edit /etc/config/network to configure the wifi interface config interface wifi option ifname "wl0" option proto static option ipaddr <IP ADDRESS> option netmask 255.255.255.0 option gateway <GW ADDRESS> option dns <DNS SERVER ADDRESS> # edit /etc/config/wireless appropriately for the local network --------------------------------- config 'wifi-device' 'wl0' option 'type' 'broadcom' option 'channel' '6' option 'disabled' '0' config 'wifi-iface' option 'device' 'wl0' option 'network' 'wifi' option 'mode' 'sta' option 'ssid' '' option 'encryption' '' option 'key' '' ---------------------------- wifi up # install nas start script /etc/init.d/nas start ln -s /etc/init.d/nas /etc/rc.d/S55nas
    YMMV with these configurations - consult the www.openwrt.org site for loads of forum posts etc on configuring OpenWRT as a client in various situations.

  5. Manually install the termios.so library from the full python build. This is required to run the python serial interface (pyserial) to access TED.
    scp <USER>@<YOUR_HOST>:/<path_to_kamikaze_build_of>/termios.so /usr/lib/python2.6/lib-dynload
  6. Plug in TED USB cable to router. You should shortly see dmesg output like this:
    usb.c: registered new driver serial usbserial.c: USB Serial support registered for Generic usbserial.c: USB Serial Driver core v1.4 usbserial.c: USB Serial support registered for FTDI SIO usbserial.c: USB Serial support registered for FTDI 8U232AM Compatible usbserial.c: USB Serial support registered for FTDI FT232BM Compatible usbserial.c: FTDI FT232BM Compatible converter detected usbserial.c: FTDI FT232BM Compatible converter now attached to ttyUSB0 (or usb/tts/0 for devfs) usbserial.c: USB Serial support registered for USB-UIRT Infrared Tranceiver usbserial.c: USB Serial support registered for Home-Electronics TIRA-1 IR Transceiver ftdi_sio.c: v1.3.5:USB FTDI Serial Converters Driver
    And you should have the device node /dev/usb/tts/0 available.

  7. Download the ted.py file originally written by Micah Dowty:
    wget http://www.bananabend.net/energy_detective/python/ted_orig.py
  8. Run with
    python ted_orig.py /dev/usb/tts/0
    and you should get output from your TED.

  9. At this point, you can modify the python script to do whatever you like with the output from TED. We modified the ted_orig.py to dump the results every second into a file in the OpenWRT's ramdisk. The modified version of the TED python script is here. We started this script with an init.d entry:
    #!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org START=50 start () { /usr/bin/python /root/ted2.py /dev/usb/tts/0 & } stop() { killall -9 python }
  10. We then created a quick shell script that used curl to post the output to a PHP script on our server using curl. This is fired from cron once per minute.
    #!/bin/sh if [ -f /tmp/ted ]; then VALUE=`cat /tmp/ted` echo ${VALUE} > /tmp/post.out /usr/bin/curl --max-time 15 <SERVER_URL>?${VALUE} >> /tmp/post.out 2>&1 else echo 'skipped' > /tmp/post.out fi
  11. The server-side php script that SERVER_URL pointed to looks like this:
    <?php # # Insert code to extablish mysql connection to database # $housecode = $_GET{'house_code'}; $kw_rate = $_GET{'kw_rate'}; $volts = $_GET{'volts'}; $kw = $_GET{'kw'}; if($kw && $housecode) { $insert = "insert into ted_data (housecode, ts, value) values ('" . $housecode . "', '" . date("Y-m-d H:i:00") . "', " . $kw . ")"; mysql_query($insert); $err = mysql_error(); if($err) { echo "ERROR: " . $err; } else { echo "OK"; } } else { echo "ERROR: Bad input"; } ?>
  12. The schema for the database looks like this
    CREATE TABLE IF NOT EXISTS `ted_data` ( `ts` datetime default '0000-00-00 00:00:00', `value` double NOT NULL, `title` varchar(256) default NULL, `annotation` text, `housecode` varchar(5) NOT NULL );
  13. We then used the PHP Google Datasource adapter found here to establish our Google Datasource.
    <?php ob_start("ob_gzhandler"); error_reporting (E_ALL ^ E_NOTICE); require_once 'MC/Google/Visualization.php'; $db = new PDO('mysql:host=' . $DBHost . ';dbname=' . $DBase, $User, $Password); $vis = new MC_Google_Visualization($db, 'mysql'); $vis->addEntity('ted_data', array( 'table' => 'ted_data', 'fields' => array( 'timestamp' => array('field' => 'ts', 'type' => 'datetime'), 'kW' => array('field' => 'value', 'type' => 'number'), 'title' => array('field' => 'title', 'type' => 'text'), 'annotation' => array('field' => 'annotation', 'type' => 'text'), ), 'where' => 'ts > date_sub(now(), interval 72 HOUR)' ) ); $vis->setDefaultEntity('ted_data'); $vis->handleRequest(); ?>
  14. And, finally, used Google's Annotated Timeline widget to render the graph. We used some JS to modify the layout of the timeline widget to integrate with the EnergyCircle look and feel - for clarity that code is not included here...
    <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load("visualization", "1", {packages:["annotatedtimeline"]}); google.loader.writeLoadTag("css", "ted.css"); google.setOnLoadCallback(drawChart); var query; function reload() { query.send(callback); } function isIE() { return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent); } function callback(result) { if(result.isError()) { alert(result); } else { chart.draw(result.getDataTable(), {displayAnnotations: true, allowHtml: true}); } setTimeout("reload();", 60 * 5 * 1000); }; function drawChart() { query = new google.visualization.Query('/ted_query.php'); query.setQuery('select timestamp, kW, title, annotation'); var div = document.getElementById('chart_div'); chart = new google.visualization.AnnotatedTimeLine(div); query.send(callback); } </script> <div style="height:825px" id='chart_div'>Loading...</div>

Please let us know if this recipe is helpful and feel free to post questions, errors, or omissions here or email info@energycircle.com.

Updated May 29, 2009 @ 13:40 for formatting and tiny content changes - more info coming!

Updated May 29, 2009 @ 14:30 to include server-side code

Comments

Awesome! Thanks for sharing!

I think this is missing some of the detail, to make it "open source" though. Steps 1-8 are all "getting data off the TED." Step 9 is "magic happens here." :)

If you shared the source of your modifications to ted-orig.py, ted_query.php, and MySQL schema, this would be a repeatable.

Hey There. I found your blog using msn. This is a very well
written article. IÌll be sure to bookmark it and come back to read
more of your useful info. Thanks for the post.
IÌll certainly comeback.

After looking over a few of the blog posts
on your web site, I honestly like your technique of blogging.
I book-marked it to my bookmark webpage list and will be checking back in the near future.
Please check out my website as well and tell me how you
feel.

What is effect of energycircle.We get energy many types. Book of Ra kostenlos

Whoa! This blog looks exactly like my old one! It's on a completely different subject but it has pretty much the same page layout and design. Wonderful choice of colors!

You could certainly see your skills in the article you write.
The world hopes for even more passionate writers such
as you who aren't afraid to say how they believe. All the time go after your heart.

Ahaa, its good discussion about this piece of writing here at this web site, I have read all that, so
aat this time me also commenting at this place Also, personally,I think you could make iit better if you could add more pictures first.
Keeep on thhe nice work,and i'll be back for updates daygs later.

BTW, it can be more helpful if you would add my twitter back :)

You have uploaded a fantastic site.

Energy is fundamental for things to change. All living things require accessible vigor to stay animated; people get such vigor from nourishment, plus the oxygen would have done well to metabolize the sustenance. Krav Maga

This website was... how do you say it? Relevant!
! Finally I've found something which helped me. Kudos!

Pretty great post. I just stumbled upon your weblog and wished to mention that I've truly enjoyed surfing around your weblog posts. In any case I will be subscribing to your rss feed and I am hoping you write again soon!

I will right away snatch your rss as I can't in finding your e-mail subscription link or e-newsletter service. Do you have any? Please let me realize in order that I may just subscribe. Thanks.

This completely rocks! It reminds me of the first TiVos or other similar boxes that people hacked up to do all sorts of cool stuff. I salute the intrepid geek that put all these bits together in the right order!

I can do all this stuff, but it's been an "on the list" item for a while (I can, but don't). There are a bunch of other similar options involving Tweet-a-Watts and other options -- check out today's WattzOn's roundup of similar mashups. There are multiple people all trying to get to the same place at that same time. Very good.

A couple of days ago, LifeHacker published this article on $40 minimal Linux computers and I was shocked (shocked, I say) that no one else commented about using it for hooking up to a TED -- it has just the ports you need: Ethernet and USB. If I could get my hands on something like this (and shell out for the TED) I think I could package up a single install.

Of course I don't really want to have another thing to plug in, and I think routers (which already are good at connectivity) should have more pluggable module and computing ability. And of course, the iPhone app :-)

All the pieces seem to be relatively in place. Now it's just a matter of assembly.

The world is changing. It's good.

Now I am going to do my breakfast, when having my breakfast
coming over again to read other news.

Cool blog! Is your theme custom made or did you download it from somewhere?

A theme like yours with a few simple tweeks would really make my blog stand out.
Please let me know where you got your theme.
Many thanks

Does the TED device support this data acquisition without the energy footprints software? That adds significantly to the price...

blalor - I believe you need to purchase the footprints software even if you don't use it. Otherwise, TED will not respond to requests to upload its data.

blalor - There is a difference in firmware. TED with footprints comes with the USB port activated, and w/o footprints, the USB port is not activated. If you have a TED without footprints, you can upgrade by purchasing footprints separately and upgrading your firmware.

I write visualization software and would love to get a hold of the raw data, so I can play with it. Is there a way you can make that downloadable?

I bought an Asus WL-500gP right away through the link above as I would be very excited to post my TED data to the internet in a similar way, but unfortunatly I get stuck after installing OpenWRT on the router. It's installed and I can ssh to it as well, but I can't get an internet connection, even though I plugged the WAN into my other router, so I can't get beyond your first box with installing the opkg packages.

Hi,

I integrated with TED by reading the TED Database and from a Windows Service I created and posting the results to http://www.currentwatchers.com, a site I created to help folks share energy observations and best practices.

The windows software is available on the site for download.

Mike

Tom, I've had my eye on the SheevaPlug, the same plug computer discussed in the LifeHacker you reference, as a way of reading TED data without tying up my laptop. The SheevaPlug development kit is only $99 and comes with Linux and a USB port (http://www.globalscaletechnologies.com/p-22-sheevaplug-dev-kit.aspx).

Someone will eventually come out with a low cost production verison but, for right now, it looks like a much better solution than a router (something I also considered but rejected -- hats off to energycircle for making it work).

Unlike you, I'm not worried about adding "another thing to plug in". It draws only 5 watts.

Have you ever thought about including a little bit more than just
your articles? I mean, what you say is fundamental and all.
However imagine if you added some great graphics or video clips to give
your posts more, "pop"! Your content is excellent but with pics and videos, this blog could undeniably be one of the very best in its niche.
Great blog!

-the instructions at: http://oldwiki.openwrt.org/OpenWrtDocs(2f)Hardware(2f)Asus(2f)WL500GPV2.html say:
"Link the packages you care about

Take a look in the resulting packages directory; you'll see there's a lot of stuff. You probably don't need to build everything in there. Instead I recommend making symlinks for only the packages you need. For example, suppose you're following the UsbAudioHowto, and you want to use madplay to decode streaming MPEGs."

OK, which packages do I care about - do I build them all?

You can build them all, or select only the ones listed in the recipe in the original post.

Next question: the recipe at: http://oldwiki.openwrt.org/OpenWrtDocs(2f)Hardware(2f)Asus(2f)WL500GPV2.html

says:

"Next, the USB2 support needs to be patched. You can review the patch at https://dev.openwrt.org/cgi-bin/trac.fcgi/attachment/ticket/3365/ssb-ehc..., and you can pull down the patch file via a little, tiny, grey link at the bottom. That patch targets kernel 2.6.25-4, which is probably not your kernel. The following appears to do an okay job of pulling down the patch, and rewriting it for kernel 2.6.25-10:"

But, for some reason, ticket 3365 is closed, so this patch is no longer available. Is it still relevant for the 8.09 branch?

Best,

Martin

You really make it appear so easy with your presentation
however I to find this matter to be actually one thing that I feel I might by no means
understand. It kind of feels too complex and very broad
for me. I'm taking a look forward in your next post, I'll
try to get the dangle of it!

Peter,

Sounds cool, but, candidly, I still need help with the recipe.

It would be great to do exactly what you did. The current trunk, of course, is different from the trunk when you did your build according to the recipe at: http://oldwiki.openwrt.org/OpenWrtDocs(2f)Hardware(2f)Asus(2f)WL500GPV2.html

For example, using the 8.09 branch, when I run
make kernel_menuconfig
I don't even get a choice for "EHCI support for Broadcom SSB EHCI core"

Furthermore, there are a bunch of packages enabled that I probably don't want or need.

So, do you happen to know what build number I should refer to when checkin out? Or, do you have a built image that is available?

I know you have a day job, but it would be fun to move this forward, and I would appreciate any suggestions you can offer.

Best,

Martin

An automatic gate can provide numerous advantages.
They are practical and convenient, easy to use and very
efficient. Securing the parameters with sturdy automatic gates has become extremely common, as more and more
people opt for this convenient solution. Basically,
everywhere you look you see automatic gates, whether it's somebody's home, a fancy mall or an office building.
Perimeter access control is affordable to all budgets.

Pretty! Thіs hаas been an incredibly wonderful article.
Thanks for providing these details.

So, your graph only shows 72 hours, which is fine. Are you purging older data from the database, or are you keeping that all?

If you're keeping it, then you've got to have probably 100,000 rows at this point. How big is that table at this point?

I'm curious if anyone has gotten this working by following the recipe. I would like to think that I'm not an idot, but I have struggled moving this project forward. It is moving, but very slowly.

The server side things have me baffled. I'm grateful for the pieces that have been shared, but I think there are more things that could be added to make the process available to a wider audience. The more people who measure, the more who save, etc...

Just thought I'd mention.. on my website there is another script:

http://www.bananabend.net/energy_detective/python/ted5.py

that is a modified version of Micah's script that write's the data directly to a MySQL database. More importantly in regards to this project, I fleshed out the parameter table to give most of the information the TED provides, which is pretty much everything you see on the Ted's LCD. Daily and monthly usage stats, dollar amounts, etc.

JDUB,
No, I haven't either. I have posted a question or two for Peter, and also heard from Peter Troast at energycircle, but am still wrestling...
Best,
Martin

has anyone got this working with pachube (www.pachube.com)? seems like an easier way to do it than all that database and google app stuff. but i haven't got an asus router to try this all out.

What's up, its nice post concerning media print, we all understand media is a enormous source of facts.

I always emailed this weblog post page to all my associates, for the reason that if like to read it then my links will too.

How do you get through with the google API?
I always receive an error:
google.visualization.Query.setResponse({version:"0.5"reqId:"0",status:"error",errors:[{reason:"invalid_query",message:"Invalid Query",detailed_message:"An error occurred: \"select timestamp, kW, title, annotation\""}]});

Is there a way around this?
I read the comments on googles home page and many people experience the same problem but no solution is posted.

Regards
Mathias

Entertainment leads us to a different world and feeds our need for
imagination and an escape from real daily life .
It is especially true for entertainment which
is more public or given by the mass media and entertainmennt
provided by movies , theatre , music , and all forms of innovative art.

If your competitors start an SEO crusade, with or without an out-of-doors seo services, you can learn much about their sales and trading tactics by assessing the keyphrases that they goal. And you can furthermore investigate if they are utilising ethical SEO practices in their crusade.

Wonderful!! this is really one of the most beneficial blogs I’ve ever browsed on this subject.I am very glad to read such a great blog and thank you for sharing this good info with us.

I just read the regularly one particular subject material. Beautiful articles or reviews, thank you to suit downloading and sharing an article content with all of us.

Online reading is not my thing. But after reading your blog I am really pleased. I don’t know about other blogs but this I will definitely keep coming back to.

I’m glad Yahoo pointed me to it. I was able to get the know-how I was searching so badly for days now.Thank You very much for your really good web page. Have a good day.It's very useful for everyone for sure.

About one-third of the energy used in the United States in 2006 went to industry. That’s not so surprising when you consider everything that falls under this economic sector. Every product we rely on—from aluminum cans to fertilizer to glass to paper products—takes energy to produce. The use of energy in industry affects every single citizen personally through the cost of goods and services, the quality of manufactured products, the strength of the economy, and the availability of jobs.e-mail marketing companies

First of all acceptance for the able notes. In absoluteness it is amazing able notes. I do be absorbed of Ruby Fortune online-kasino pelata nyt your determined accoutrement and be constant about your suggested. I can exhausted on you accession abode breadth one can accession gigantic aides advertent schooling.

First of all acceptance for the able notes. In absoluteness it is amazing able notes. I do be absorbed of your Ruby Fortune online-kasino pelata nyt determined accoutrement and be constant about your suggested. I can exhausted on you accession abode breadth one can accession gigantic aides adventurer schooling.

Zero-Obligation Marketing Evaluation

Find out what's working, what's not, and what to do about it. It's free.