Alarmclock

by marc 29. december 2014 06:23

It happens quite often that i see a cool Raspberry Pi project that i want to have working in my own home.  Basic functionality usually is operational in no time.Then the real challenge begins.

 

How to fit this in as a real monkeyproof/wifeproof solution for everyday use?

 

In this case I wanted an alarmclock. Not just an alarm that beeps at 6.30 in the morning, but a little screen that tells me time, google calendar events for the day, the weather,etc.

Raspberry, touchscreen, speaker. Installed a webserver to display some webpages with time, weather and events and  to control MPD.

Ready?

 

 

 

The raspberry has a light indicator (red). The usb wifi dongle flickers blue. The screen has white backlight visible.

Usb wifi dongle light flickering is very annoying in an otherwise dark bedroom. But there is no configurable setting to switch this off. I saw some forum posts on compiling new versions for specific kernels. Too difficult for me. So for this I had to use tape. I also taped off the raspberry light. The backlight of the screen was killed by switching off the screen during daytime and in the middle of the night with the help of a conjob.

But.. When i awake somewhere during the night, i do want to see the time. But the screen is off.

How to solve this? No solution found yet.

The clockradio is another item. I want ease of use when setting an alarmtime, and ease of use on stopping the alarm. 

A cronjob can switch on the radio at a specific time during weekdays. But cronjobs are not easily disabled when there happens to be a day you can sleep in.  Nor can I easily change the time.

Still I sticked to using cronjobs. The cronjob starts up MPC at a specific time but sets no volume. So by manually setting the volume to zero, I can skip an alarm. Of course then I have to remember to turn up the volume the next day. For occasional later or earlier alarms I can use http://raspctl.com This allows for webbased alarm setting, but strangely requires a specific date to be entered. 

Ease of use for stopping the alarm. Throwing the alarmclock against the wall is not an option of course, but with a sleepy head trying to find the right button is also not desirable. The solution is found in stopping MPC by touching the screen (the entire div leads to url that stops mpd). 

Tags:

Wilde Ideeën

Twitterende Kerstboom

by marc 22. december 2013 06:00

De kerstboom aan de tijdschakelaar? Nee, laat de mensen op internet onze kerstboom maar aan en uitzetten!

 

Benodigdheden:

klikaan klikuit schakelaar -- om de kerstverlichting aan en uit te kunnen zetten

homewizard -- om de klikaan klikuitschakelaar aan te kunnen sturen

phpscript -- om tweets met een bepaalde hashtag te kunnen lezen, op te slaan in db, laatste (onbehandelde) tweet(s) te selecteren en dan de actie voor de schakelaar te gaan bepalen.

cronscript -- iedere x minuten het phpscript uitvoeren. eerst gezet op 1 minuut. Maar voor de vrouw-des-huizes-acceptatiefactor later op 10 minuten gezet. (dit had eventueel ook met een keuze voor een andere hashtag beinvloed kunnen worden.

 

onderstaande script aanpassen/invullen:

- api gegevens twitter

- zoekstring op twitter waarop actie gebaseerd gaat worden

- ip adres van de homewizard

- switch nummer 

- mysql database 

 

 

<?php

ini_set('display_errors', 1);

require_once('TwitterAPIExchange.php');

 

/** Set access tokens here - see: https://dev.twitter.com/apps/ **/

$settings = array(

    'oauth_access_token' => "token",

    'oauth_access_token_secret' => "secret",

    'consumer_key' => "key",

    'consumer_secret' => "secret"

);

 

/** Perform a GET request and echo the response **/

/** Note: Set the GET field BEFORE calling buildOauth(); **/

$url = 'https://api.twitter.com/1.1/search/tweets.json';

$getfield = '?q=%23zetdiekerstboommaar&result_type=recent';

$q = 'zetdiekerstboommaar';

$requestMethod = 'GET';

$twitter = new TwitterAPIExchange($settings);

$response = $twitter->setGetfield($getfield)

             ->buildOauth($url, $requestMethod)

             ->performRequest();

 

/**var_dump(json_decode($response,true));**/

 

$jsonobj=json_decode($response,true);

 

if($jsonobj != null){

$con = mysql_connect('host', 'dbname', 'user');

if (!$con){

die('Could not connect: ' . mysql_error());

}

 

foreach($jsonobj['statuses'] as $item){

              /**var_dump($item);**/

$id = $item['id'];

$created_at = $item['created_at'];

$created_at = strtotime($created_at);

$mysqldate = date('Y-m-d H:i:s',$created_at);

  $from_user = mysql_real_escape_string($item['user']['screen_name']);

              if ($from_user == "") { $from_user = mysql_real_escape_string($item['user']['name']);}

  $from_user_id = 0;

$text = mysql_real_escape_string($item['text']);

$source = mysql_real_escape_string($item['source']);

$geo = $item['geo'];

$iso_language_code = "en";

$profile_image_url = "na";

$to_user_id = 0;

 

mysql_select_db("tweets", $con);

$query = "INSERT into tweets VALUES ($id,'$mysqldate','$from_user',$from_user_id,'$text','$source','$geo','$iso_language_code','$profile_image_url',$to_user_id,'$q','0')";

$result = mysql_query($query);

  }

mysql_close($con);

}

 

/** determine requested switchaction **/

 

$con = mysql_connect('host', 'dbname', 'user');

if (!$con)

{

die('Could not connect: ' . mysql_error());

}

 

$query="SELECT t.id, t.from_user, t.text, t.created_at FROM tweets.tweets t,

(SELECT max(id) as maxid FROM tweets.tweets) maxresults

WHERE t.id = maxresults.maxid AND t.used=0 AND t.from_user like '%'

AND t.id > (SELECT max(t2.id) FROM tweets.tweets t2 WHERE t2.used = 1)";

$result=mysql_query($query);

$num=mysql_numrows($result);

mysql_close();

 

$OnOff="empty";

$user="nobody";

$i=0;

while ($i < $num) 

{

$OnOff=mysql_result($result,$i,"text");

$user=mysql_result($result,$i,"from_user");

echo $OnOff."<br>";

echo $user."<br>";

$i++;

}

 

$action="Neutral";

if (strchr($OnOff,"zetdiekerstboommaaraan")) {$action="On";}

if (strchr($OnOff,"zetdiekerstboommaaruit")) {$action="Off";}

echo $action;

 

 

/** get switch status **/

 

$jsonurl = "http://192.168.x.x/password/get-sensors";

$json = file_get_contents($jsonurl);

$data = json_decode($json,true);

$switches =  $data['response']['switches'];

 

$stand = "onbekend";

foreach($switches as $switch){

        /**echo $switch['id']." <br>";

        echo $switch['name']." <br>";

        echo $switch['status']."<br>";**/

if ($switch['id']=="0" and $switch['status']=="off"){ $stand="Off";}

if ($switch['id']=="0" and $switch['status']=="on"){ $stand="On";}

}

 

echo $stand."<br>";

 

 

/** do actions **/

 

/** action: set switch **/

if ($stand=="Off" and $action=="On") 

{

shell_exec("wget 'http://192.168.x.x/password/sw/0/on'");

}

 

if ($stand=="On" and $action=="Off") 

{

shell_exec("wget 'http://192.168.x.x/password/sw/0/off'");

}

 

 

/** action: tweet **/

 

$consumerKey = 'key';

$consumerSecret = 'secret';

$oAuthToken = 'token';

$oAuthSecret = 'secret';

 

include 'twitteroauth/twitteroauth.php';

$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $oAuthToken, $oAuthSecret);

/**if ($action=="Neutral") 

{ $text = "$user bedankt";

$tweet->post('statuses/update', array('status' => "$text"));

}**/

if ($stand=="Off" and $action=="On") 

{ $text = "$user heeft mij aangezet!";

$tweet->post('statuses/update', array('status' => "$text"));

}

if ($stand=="Off" and $action=="Off") 

{ $text = "$user wilde mij uitzetten, maar ik stond al uit";

$tweet->post('statuses/update', array('status' => "$text"));

}

if ($stand=="On" and $action=="Off") 

{ $text = "$user heeft mij uitgezet..";

$tweet->post('statuses/update', array('status' => "$text"));

}

if ($stand=="On" and $action=="On") 

{ $text = "$user wilde mij aanzetten, maar ik stond al aan";

$tweet->post('statuses/update', array('status' => "$text"));

}

echo $text;

 

 

/** action: update db **/

$con = mysql_connect('host', 'dbname', 'user');

 

if (!$con)

{

die('Could not connect: ' . mysql_error());

}

 

$query=" UPDATE tweets.tweets SET used=1";

$result=mysql_query($query);

mysql_close();

 

?>


Tags:

Wilde Ideeën

Twitterende Zonnepanelen

by marc 13. februari 2013 08:02

In de donkere dagen voor kerst 2012 werden bij ons zonnepanelen geplaatst. Van de gemeente mochten ze niet aan de 'goede' kant. Dat zou afbreuk doen aan het ononderbroken aangezicht van dakpannen van onze 26-onder-één-kapper. Ondanks dat via google maps te zien is dat 6 huizen verder wel zonnepanelen en slechts 1 huis verderop een dakraam het ononderbroken aanzicht onderbreken... De zonnepanelen zijn nu dus west-noordwest georienteerd en over de terugverdientijd hoeven we het niet meer te hebben.

 

Toch blijft de vraag: doen ze het? hoeveel vermogen leveren ze nou? Om deze vragen te beantwoorden kan ik de hele dag voor de meterkast gaan staan en kijken of die meter nu eindelijk eens een keer terugdraait. Andere optie is om het programma Sunny Explorer van de leverancier van de omvormer te gebruiken en het geleverde vermogen uitlezen. Beide opties voldoen niet aan het criterium om 's avonds op de bank via de iPad het vermogen te kunnen aflezen. 

 

Zoals zovaak bleek door een eenvoudige zoektocht met Google dat ik lang niet de eerste was met deze vraag en de daarbij gestelde randvoorwaarde van bank/iPad.

 

Op http://ictoblog.nl/raspberry-pi/raspberrypi-pvoutput en op http://www.gzeel.nl/sma-bluetooth-pvoutput/ bleken uitstekende handleidingen te staan om mijn probleem op te lossen. Overigens bleek in mijn geval de op deze blogs genoemde versie van sma-bluetooth niet te werken. Op https://code.google.com/p/sma-bluetooth/source/clones staan echter een aantal andere clones. Uiteindelijk vond ik een werkende variant. 

Daarmee had ik m'n eerste succesbeleving. Iedere 5 minuten wordt het vermogen van de zonnepanelen uitgelezen, in een database gezet en geupload naar pvoutput.org. Alle details zijn altijd en overal op te vragen!

Op de eerder genoemde blogs werd ook op de mogelijkheid gewezen om iedere dag een rapport per email te ontvangen. Ik heb gekozen voor een variant hierop. Ik besloot mijn zonnepanelen een eigen twitteraccount te geven. Met mijn eigen twitteraccount volg ik mijn zonnepanelen-account. Zodoende hoef ik niet iedere dag te surfen naar mijn eigen output op een specifieke website, maar kom ik iedere dag een aantal kerngegevens van de zonnepanelen vanzelf tegen in mijn twittertimeline. 

 

 

Voor de geïnteresseerden. Om de output zoals die in de database staat om te vormen naar een dagelijkse tweet heb ik de volgende stappen ondernomen.

 

1. tutorial mbt tweeten vanuit een php-script: http://www.wescutshall.com/2011/09/how-to-post-to-twitter-from-php/

2. maken van php-script (zie hieronder)

3. php-script en files vanuit tutorial in mapje op de webserver geplaatst

4. via crontab dagelijks om 20:25 het php-script uitvoeren zodat ik tijdens het praatje van Gerrit Hiemstra kan kijken wat mijn zonnepanelen van het weer vonden (tweede succesbeleving).

 

NB Zodra de vogels op het dak teveel op de panelen hun behoefte doen, kan ik er op vertrouwen dat de panelen dat vervolgens naar mij zullen tweeten. 

 

---php script ---

<?

$username="user";
$password="password";
$database="database";

mysql_connect(localhost,$username,$password);
@mysql_select_db($database) or die( "Unable to select database");
$query="SELECT Date(d1.DateTime) as Date, 
max(d1.ETotalToday) as EToDate, max(d1.ETotalToday)- min(d1.ETotalToday) as EToDay, 
max(d1.CurrentPower) as PeakToday, 
(Select Min(Time(d2.DateTime)) From smatool.DayData d2 where 
          d2.CurrentPower = (SELECT max(d3.CurrentPower) 
          FROM smatool.DayData as d3 where Date(d3.DateTime) = 
                   CURDATE()) and Date(d2.DateTime) = CURDATE() ) as PeakTime, 
max(d1.ETotalToday) / DATEDIFF(CURDATE() , '2012-12-04') as DAvg 
FROM smatool.DayData as d1 where Date(d1.DateTime) = CURDATE()";

$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();

$i=0;
while ($i < $num) {
$Date=mysql_result($result,$i,"Date");
$EToDate=mysql_result($result,$i,"EToDate");
$EToDay=mysql_result($result,$i,"EToDay");
$PeakToday=mysql_result($result,$i,"PeakToday");
$PeakTime=mysql_result($result,$i,"PeakTime");
$DAvg=mysql_result($result,$i,"DAvg");
 
$consumerKey = 'key';
$consumerSecret = 'secret';
$oAuthToken = 'token';
$oAuthSecret = 'secret';

include 'twitteroauth/twitteroauth.php';

$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $oAuthToken, $oAuthSecret);
$text = "$Date: $EToDay kWh  Total: $EToDate kWh  Average: $DAvg  Peak: $PeakToday W at $PeakTime  ";

// Send tweet 
$tweet->post('statuses/update', array('status' => "$text"));

$i++;
}

?>

https://twitter.com/PJBZonnepanelen

Tags: , , , ,

Wilde Ideeën

Laaghangend Fruit

by marc 7. juni 2011 11:07

Je kent ze wel die kantoor hydroplanten. Altijd hetzelfde type. Waarom niet groente- en fruit op een kantoortuin plaatsen? Heel gezond af en toe een komkommer, tomaat of appel tussendoor te eten. Het management kan het laaghangend fruit plukken. Europese subsidie om mensen gezond te laten eten. Maatschappelijk verantwoord en duurzaam ondernemen. Weer zo'n briljant idee dat waarschijnlijk nooit verder komt.

Tags:

Wilde Ideeën

Midgetgolf

by marc 23. september 2010 07:19

Thuis doe je het nooit. Op vakantie doe je het heel vaak. Midgetgolfen.

Vreemd eigenlijk, want de gemiddelde midgetgolfbaan bij een camping of een restaurant is minstens 20 jaar oud. De verf bladdert van het beton af. Alles ligt scheef, er liggen bladeren en steentjes en overal groeit onkruid. Het is een wonder als je nog een keer het balletje in het putje krijgt.

Tijd voor een nieuw concept. Ik zeg: iedereen met een voortuin kan best 1 midgetgolflane aanleggen. Dat komt de creativiteit en varieteit aan banen enorm te goede. De een verzint iets met ophaalbruggetjes, de ander iets met tunnels. Bovendien kun je op die manier een mooi parcours door de wijk aflopen. Goed voor de buurtintegratie. Iedereen met een mooi ontwerp voor een baan mag zich bij mij aanmelden. De voortuin ligt er klaar voor. 

Tags:

Wilde Ideeën