Eplepresseloggen

En av verdens kjedeligste bloggposter, men jeg liker å ha oversikt…

2021: ca 80 liter juice + 60 liter cider. ca 40% epler fra nr 6, ca 30% Torstein fra Høyenhall og resten egne
2014 : 80 liter
2014 : 30 liter (ca halvparten av eplene fra andre)
2013 : 69 liter
2012 : 30 liter
2011 : 57 liter
2010 : 50 liter
2009 : 38 liter
2008 : 88 liter (mye epler fra naboer)
2007 : 12 liter
2006 : 83 liter

Posted in epler | Comments Off on Eplepresseloggen

Create GeoJSON in php

GeoJSON is a text format for encoding various geographical structures. I have a large number of point data with various extra information stored in a postgresql data base. I fetch all the data into an array in php, using PDO::FETCH_ASSOC, that is each row that has been fetched is an item in a numerical array, for each row, the various fields are coded as an associative array, so I have a structure like

Array
(
    [0] => Array
        (
            [id] => 210
            [name] => Sellafield
            [lat] => 54.43
            [lon] => -3.52
            [type] => Reprocessing plant
            [country] => Great Britain
        )

    [1] => Array
        (
            [id] => 177
            [name] => Dounreay
            [lat] => 58.57
            [lon] => -3.73
            [type] => Reprocessing plant
            [country] => Great Britain
        )
)

Now I want to use the lat and lon field to create the coordinate fields in GeoJSON and store the rest of the information as properties. Having the dataset stored as $dataset, I run the following code

$minlat=100;
$maxlat=-100;
$minlon=400;
$maxlon=-200;
foreach($dataset as &$item){ # Uses a pointer to refer to $item, so that changes are reflected in $dataset
   $item['geometry']['type']='Point';
   # Must make sure the coordinates are stored as numbers, not strings      
   $lon=$item['lon']*1;
   $lat=$item['lat']*1;
   $item['geometry']['coordinates']=array($lon,$lat);
   $minlon=min($minlon,$lon);                                                                                    
   $maxlon=max($maxlon,$lon);                                                                                    
   $minlat=min($minlat,$lat);                                                                                    
   $maxlat=max($maxlat,$lat);                                                                                    
   unset($item['lat']);
   unset($item['lon']);
   foreach($item as $k=>$v){  
      # Don't want to mess with geometry as it is already set
      # Id should also be set directly.
      if(!($k='geometry' || $k=='id')) {
         # Must make sure that numeric values are correctly handled
         if(is_numeric($v)?$v*1:$v;
         $props[$k]=$v;
         unset($item[$k]);
      }
    }                                                                                                      
    $item['type']='Feature';                                                                          
    $item['properties']=$props;
  }
  $dataset=array("type"=>"FeatureCollection","features"=>$dataset);
  $dataset['bbox']=array($minlon,$minlat,$maxlon,$maxlat);
  # Defining crs for WGS84 lat/lon
  $dataset['crs']=array("type"=>"name","properties"=>array("name","urn:ogc:def:crs:EPSG::4326"));  
$json=json_encode($dataset);
Posted in Diverse | Comments Off on Create GeoJSON in php

Eplelogg 2013

Eplepressingen er i gang igjen, nå med nyinnkjøpt kvern

13. oktober
12+16 kg james grieve presset til 15 liter juice

27 oktober
32 kg James Grieve presset til 19 liter juice
8 kg James Grieve + 8 kg torstein 9 liter juice,

17 kg torstein (veiefeil) presset til 9 liter juice.

9.november
Siste rest av Torstein + noen andre rester:

16 kg torstein ble snaut 8 liter juice
16 kg torstein + lagret aroma, snaut 9liter juice

Avslutter årets sesong med 69 liter juice fra 127 kg epler. Lagrer ca 20 kg til Mye stort, spesielt på aroma og torsten. En god sesong!

Helt klart dårligere utbytte fra torstein enn fra james grieve. Fant også ut at pakker på 5 kg er i meste laget for pressen. Regner med å ta en eller to runder med torstein senere, muligen også en runde med aroma som ble plukket for et par uker siden.

Posted in epler | Comments Off on Eplelogg 2013

Eplepresserioppgradering

Årets oppgradering i eplepresseriet er en fruktkvern. til erstatning for tidligere bruk av en vanlig kjøkkenmaskin

Eplepresseriet

Eplepresseriet

Eplekverna har kniver som kutter eplene og drar dem inn mellom valser som knuser dem.

Eplekverna har kniver som kutter eplene og drar dem inn mellom valser som knuser dem.

4 kg epler klar for kverning.

4 kg epler klar for kverning.

Den blir grovere enn ved bruk av kjøkkenmaskin, men det ser ut for å være en fordel ved pressingen

Kvernet fruktmasse. Den blir grovere enn ved bruk av kjøkkenmaskin, men det ser ut for å være en fordel ved pressingen

Etter to runder med pressing må det sies at dette var en svært god investering. Jeg plasserte kvernen oppå en plastkasse og satt en stor (ca 6 l) plastbolle nedi for å ta imot de oppmalte eplene.

  • Maler opp 4 kg epler på ca 2 minutter. Så kan eplene enkelt overføres til pressa. Kan nå enkelt presse 4×4 kg, tidligere var det ikke praktisk mulig med mer enn 4×3 kg.
  • Eplene malt opp på dette viset ser ut for å gi fra seg juice lettere. Tidligere har jeg måttet jobbe en del for å få ut 1 liter juice pr 2 kg epler, nå får jeg en drøy liter juice pr 2 kg epler med mindre arbeide med pressa
  • Enkel å rengjøre, spyles med hageslange etter at dagens arbeide er avsluttet
  • Sannsynligvis mer holdbar. Har alltid vært engstelig for at kjøkkenmaskinen skal bryte sammen når den må tygge gjennom 30-40 kg epler i løpet av noen få timer.
  • Ved oppkverning av store epler, kan det være nødvendig å dele dem opp, de kan bli liggende i forhold til knivene så de ikke blir ført ned mellom valsene
Posted in epler | 2 Comments

Postgres in python using flask-psycopg2

Not the most well-documented module I’ve ever seen…

To make it connect to your database of choise, in the app-settings, feed in

PSYCOPG2_DATABASE_URI=”pgsql://dbuser:dbpassword@dbhost/database”

e.g.

PSYCOPG2_DATABASE_URI=”pgsql://postgres:Secr1tPsswrd@localhost/postgres”

Posted in Diverse | Comments Off on Postgres in python using flask-psycopg2

.44 magnum cortado

Come on, make my coffee!

This coffee is strong enough to defend itself

This coffee is strong enough to defend itself

Posted in Diverse | Comments Off on .44 magnum cortado

Gymtider

Gymtimene på 80-tallet var for de sterke og minnene kommer strømmende på.

Gymlæreren min i 2. og 3. vgs hadde stor tro på at langdistanseløp var det eneste saliggjørende. Ut for 5000m på Bislett. Han sto på kanten og sekunderte. “14 etter 45:50” ropte han da jeg luntet forbi. “Hæ” svarte jeg, da jeg ikke hadde filla anelse om hva han mente (som jo tradisjonen var i gymtimer skal jo ikke noe forklares og jeg forsto ikke sekunderingen hans før mange år senere). Etter noen flere runder falt jeg ut av skjemaet hans. Jeg drev det også relativt langt til skulking i gymtimene etter at jeg hadde en skade å unnskylde det på. Jeg og en kompis kom oss helt til Tøyenbadet en gang vi hadde svømming, men endte opp i kafeen… “Hva om kommer nå?” sa kompisen “Da løper vi, da kjenner han oss ikke igjen” svarte jeg. Og kompisen holdt på å le seg i hjel – jeg forsto ikke før lenge etterpå at han hadde sett det absurde i at gymlæreren skulle se oss løpe, jeg tenkte bare på å skygge banen raskt nok.

Heldigvis var jeg alltid mest selvironisk i forhold til mine ytelser i gymtimene – men det var vel ikke det som var meningen med det hele?

Posted in Diverse | Comments Off on Gymtider

Client based web-mapping

Maps with R – part III shows how to make an active svg-map from R. In that example, a specialiced data set was used. I have redone it by using a map pulled in from postgis and also added on some more functionallity, some of it may be extened further to make a kind of client-based web-gis application. This examnple map uses a continous color scale for a map of discrete values. This is a bad idea, but is used here to simplify the example.

Moving the mouse pointer over the map shows a tooltip with some selected information for each polygon. When clicking on a polygon, the color changes and a callback to the web pages makes the web page show the ID of the polygon. This can of cource be used to show more information, possibly fetched through an ajax call.

The svg-map is prepared through R. A number of pakages must be loaded:
library(gridSVG)
library(sp)
library(lattice)
library(latticeExtra)
library(maptools)
library(colorspace)

I have a variable called “map” that is a map pulled in from a postgres database.
map=readOGR("PG:dbname=database user=username password=password",layer=<name of the table in postgis>)

Some parts must be prepared before the svg-export can be run:

grid.newpage()
set_Polypath(FALSE)
panel.str < - deparse(panel.polygonsplot, width=500) panel.str <- sub("grid.polygon\\((.*)\\)","grid.polygon(\\1, name=paste('ID', slot(map, 'data'\\)\\$gid\\[i\\], sep=':'))", panel.str) panel.polygonNames <- eval(parse(text=panel.str),envir=environment(panel.polygonsplot)) p <- spplot(map["category"], panel=panel.polygonNames) eval(p) set_Polypath(TRUE)

For other use, two lines must/ may be altered:
panel.str < - sub("grid.polygon\\((.*)\\)","grid.polygon(\\1, name=paste('ID', slot(map, 'data'\\)\\ $gid\\[i\\], sep=':'))", panel.str)

map is the name of the variable in which the map is stored.
gid is the name of the polygon id.
This lines makes an ID of each polygon that is made as "ID:" and the value of gid for each polygon.

p < - spplot(map["category"], panel=panel.polygonNames)

Again, map is the variable holding the map, category is the variable I want to be used for coloring the map.

Thereafter, the graphical objects (grobs) that we want to work on has to be enumerated:

## grobs in the graphical output
grobs < - grid.ls() ## only interested in those with "ID:" in the name nms <- grobs$name[grobs$type == "grobListing"] idxNames <- grep('ID:', nms) IDs <- nms[idxNames]


for (id in unique(IDs)){
# Need to get back the gid-value
x < - unlist(strsplit(id, 'ID:')) i=as.numeric(x[2]) # Looks up the map element with the corresponding gid n=which(map$gid==i) # Picks out values of category and shape_area for making the tooltip info=paste(id,"->",map$category[n],'(',map$shape_area[n],'m2 )')
g < - grid.get(id) ## attach SVG attributes # Defines attributes for the respective polygons. the javascript functions is defined in "tooltips.js" (see below) grid.garnish(id, onmouseover=paste("showTooltip(evt, '",info,"')"), onmouseout="hideTooltip()", onclick="mark(evt)", class=paste('cc',map$categorycode[n],sep=''), name=info) } # The file containing the javascript functions grid.script(filename="tooltip.js") svgname="svgtest.svg" gridToSVG(svgname)

This will produce the svg-file svgtest.svg and a very simple (too simple) html-file, svgtest.svg.html. The file tooltip.js must be available in the same directry as the svg.

The function mark(evt) is calling
parent.showalert(txt);
The parent object is the webpage that contains the svg-file, so the showalert(txt) function must be defined in that page. In this case, it is as simple as function showalert(txt){
document.getElementById('Showinfo').innerHTML=txt;
}

The page is available at http://sickel.net/misc/Geilo_annomap.svg.html

Possible further development:

* Click on an item in the legend to get all items of that class marked (they are already set to the same class)
* Fetch more information from a backend server when clicking (or for the tooltip)
* Change the color coding of the map (eg by fetching information from the backend

If this is to be run under R v 2.x, (e.g. on an older Ubuntu LTS) the available packages is lacking two functions, they may be provided through the following stubs:


grobDescent< -function(x=0,y=0,z=0){ return(unit(1,"npc")) } grobAscent<-function(x=0,y=0,z=0){ return(unit(1,"npc")) }

Posted in Diverse | Comments Off on Client based web-mapping

Om å lage en scene

Enhver hage med respekt for seg selv bør ha en festival fra tid til annen- og da trenges det en scene.

Vår scene blir bygget hovedsaklig av 2″x6″,det er mulig det kunne holdt med 2″x4″, men det var nå en gang 2″x6″ jeg hadde liggende første gangen vi skulle bygge scene. Scenen har en grunnflate på ca 5×4 meter (breddexdybde) og en høyde på ca 2.5 meter (må kunne gjøre en “hoppestopp”) På grunn av fasongen på plenen der den blir bygget, er den litt dypere på den ene siden enn på den andre.

Vi bygger først de to siderammene, deretter settes de opp med støtter i underkant, slik at bærebjelkene for taket kan legges opp.

I bakkant ble det bygget et trommepodium på ca 2×2 meter, for å sikre at dette ble stabilt, la vi bærebjelker relativt tett (ca 40 cm avstand)

Vi la opp en stående 2″x6″ i forkant for å bære taket. I bakkant la vi på en 2″x4″ i høyde med rammen, dermed ble det et fall på ca 15 cm over ca 2.5 meter. Stående 2″x6″ ble lagt i lengderetningen. Dette fallet ser bra ut, men det er litt lite for å få regnvann til å renne unna. Det er viktig å bruke en god presenning som kan strammes godt opp til tak dersom det er fare for nedbør. Det er også satt opp en bjelke bakerst på venstre side som ikke skal bære noe, men som definerer bakre hjørne på scenen.

Vi brukte to presenninger for å lage vegger. Den ene var bakvegg og høyre side (sett forfra) den andre var venstre side og overlappet et par meter på bakveggen. Ved å ikke feste bakveggen for mye i enden, ble det mulig å komme inn på scenen bakfra. En bagasjestropp rundt en av bjelkene ble brukt for å feste bakveggen og samtidig gjøre det mulig å åpne.

Tverrliggerene her er, sett forfra:
2″x4″ (ny) som bærer taket i bakkant.
Skrå lekt som er feste for bakveggen .
Rett lekt som er feste for avslutingen av venstre vegg.

Med presenninger på plass. Skrålekten holder bakveggen

Noen paller ble brukt som underlag for forsterkerene

En lekt festet i forkant blir feste for takpresenningen.

Taket må strammes godt opp i bakkant:

Klar for soundcheck:

og konsert:

Neste gang scenen settes opp, vil vi montere belysningen i fremkant av scenen.

Posted in Diverse | Comments Off on Om å lage en scene

Automatic datavalidation in postgres

I have a system that continously logs various environmental parameters at home. Occasionally one of the sensors delivers some wrong readings and I would like to stop them from showing up in analyses and plots. To do this, I am inserting the data through a function that autmatically flags data that have too high or too low values – too high and low being defined for each physical sensor.

The part of the database that helps me achieve this is defined as
create table measure(
id serial primary key,
value float not null,
sensorid integer references sensor(id),
use boolean not null default true,
timestamp datetime default now()
)

When I am using data, I am reading them from the view measure_qa defined as
create view measure_qa as
select * from measure where use=true

Data about each physical sensor is stored in table sensor:

create table sensor(
id serial primary key,
typeid integer references type(id),
name varchar not null,
maxvalue float not null,
minvalue float not null
)

and for each sensor type in table type:

create table type(
id serial primary key,
name varchar,
unit varchar)

To insert data, I have defined the function addmeasurement as

CREATE FUNCTION addmeasure(double precision, integer) RETURNS integer
LANGUAGE plpgsql
AS $_$ declare
sval float:=$1;
sid integer:=$2;
mx float;
mn float;

begin
select minvalue,maxvalue into mn,mx from sensor where id=$2;
insert into measure(sensorid,value,use) values(sid,sval,mnsval);
return 0;
end;
$_$;

By calling addmeasure with the reading and the sensor id as parameters, it will check the allowed max and min values for the actual sensor and .set the use-field accordingly – if the value is within the allowed span, it is true, else it is false – and the value will not be used. It could also be possible to add in validation if the value has been fluctuating too much within a given timespan – I may implement that later on. In that case, I must consider how long time has gone since the last valid data point has been inserted and how much the data should be allowed to change per time unit.

I could also have made the use-field a varchar field (or as a foreign key to a lookup table) – then I could have had e.g. “OK” as default value and the value for data that should be used later on, and I could have made a difference between data points that were automatically discarded and data points that I have manually marked as invalid.

A important, but potentially difficult part is to set the max and min values right. They should trigger on as many error as possible without flagging valid data as invalid. It might be useful to know how the various sensors fails. E.g. I am using some ds18b20 temperature sensors. If they are not initiated properly, they may return either -127, +85 or 0 °C. I live in a place where the outdoor temperatures may go below freezing for several month of the years, so for an outdoor sensor, I cannot automatically filter out 0°C errors, so I set the limits to -50 / +60 which is far outside observed temperatures here but for the indoors sensors, (which never should go below 15 or above 45, I can set the limits to 2 and 40 °C.

Posted in Data | Comments Off on Automatic datavalidation in postgres