Hack Grand Forks – 311

I’ve been thinking about this for a while, and finally took a few evenings to do it. I built a Mastodon bot that toots each Grand Forks 311 request: https://botsin.space/@hackgfk_311. It also crossposts at https://twitter.com/hackgfk_311.

The code can be found at https://github.com/mattbk/hack-grand-forks. Yes, I built it in R.

Mastodon toots from @hackgfk_311@botsin.space.

Why “hack”? In the sense that this is information that should be more available to people, and I’m making it more available without going to a separate location. Perhaps something good can come of it.

Counterpoint API (quick notes)

Looks like first you would grab the counterpoint ID from here: https://counterpointapp.herokuapp.com/api/v1/counterpoints
EERC is counterpoint_id 606. Could select by bounding box (lat/long) too. This includes a list of counts (just labeled “id”) but no actual counts, so you could do time/date collection stat comparisons from there as well.
Then you can pull up actual counts from https://counterpointapp.herokuapp.com/api/v1/counterpoints/606 where the counterpoint_id is named at the end. This gives you a list of counts, including data.
It looks like minutes start/end on the second that the count was started, so aggregation by minute (not second) should be used.
It looks like minutes without data are excluded, e.g. no 12:51:52 minute is included here (EERC 606):
{"id":281510,"count_session_id":18223,"timestamp":"2016-06-21T12:51:56.000Z","bike_generic":0,"bike_adult":0,"bike_child":0,"bike_baby":0,"bike_cargo":0,"bike_child_trailer":0,"walk_generic":0,"walk_adult":0,"walk_child":0,"walk_stroller":0,"walk_disability":0,"walk_skateboard":0,"walk_visually_impaired":0,"walk_physically_impaired":0,"vehicle_personal":2,"vehicle_car":0,"vehicle_semi":0,"vehicle_moto":0,"vehicle_transit":0,"vehicle_oversized":0,"objectId":null,"gender_m":0,"gender_f":0,"gender_o":0,"onePerson":0,"twoPerson":0,"threePerson":0,"fourPlusPerson":0},{"id":281511,"count_session_id":18223,"timestamp":"2016-06-21T12:53:56.000Z","bike_generic":0,"bike_adult":0,"bike_child":0,"bike_baby":0,"bike_cargo":0,"bike_child_trailer":0,"walk_generic":0,"walk_adult":0,"walk_child":0,"walk_stroller":0,"walk_disability":0,"walk_skateboard":0,"walk_visually_impaired":0,"walk_physically_impaired":0,"vehicle_personal":5,"vehicle_car":0,"vehicle_semi":0,"vehicle_moto":0,"vehicle_transit":0,"vehicle_oversized":0,"objectId":null,"gender_m":0,"gender_f":0,"gender_o":0,"onePerson":0,"twoPerson":0,"threePerson":0,"fourPlusPerson":0}

Resetting read_only in Elasticsearch

Rather than messing with curl, I went the long way and installed Kibana. It takes a little while to unzip. Run it in a very similar way to Elastisearch (bin\kibana.bat). Go to http://localhost:5601/app/kibana#/dev_tools.

Paste in the solution from here:

PUT /<yourindex>/_settings
{
  "index.blocks.read_only_allow_delete": null
}

You may have run into this because you are close to the disk space limits. Rather than modifying those through Kibana, you can add them directly into elasticsearch\config\elasticsearch.yml.

Babboe City Review, Part 2: First Impressions

Previous post: Babboe City Review, Part 1: Ordering and Shipping.

I’ve obviously not gone into as much detail as I had hoped with unboxing and building, but here are first impressions after about 60 miles of commuting without kids.

  • Lights are cheap and plastic
  • Pedals are small and slippery
  • Fenders are great
  • Gearing seems good
  • Takes a bit to get up to speed
  • Upright and fun to ride, easy launch and foot down, even with saddle in right spot
  • Box squeaky until frame bolts tightened
  • Narrow bars, but good so you don’t oversteer
  • Corners well at speed
  • Not great at sharp turns on ice/snow
  • Saddle goes high enough
  • Keys seem flimsy
  • Harness is rudimentary and could be replaced
  • Turns some heads but not all
  • No intersection visibility problems yet
  • Length/width is similar to bike+burly, width similar to snowblower
  • Can’t see front wheel with rain cover on (not a huge deal)
  • Plastic chainguard–will it hold up?
  • All in all, very satisfied so far

 

Babboe City Review, Part 1: Ordering and Shipping

Since I’ve wanted a cargo bike for some time now (and saved up my pennies), I finally placed an order for a Babboe City and two accessories (rain tent and toddler seat) with myamsterdambike.com (MAB) on Friday, February 9th. This post will summarize the update process on shipping. If you are planning to purchase from a local shop (and you should, if you have one that stocks cargo bikes), you can skip this post.

I plan to write a series of posts about this bike as it arrives, gets unboxed, assembled, and ridden. A more detailed post about “why buy a cargo bike” and “why this cargo bike” is planned as well.

Things got interesting when Package 1 was delivered, because it contained the rain tent for a Babboe Curve, not a Babboe City (which I had ordered). I emailed My Amsterdam Bike and they will be shipping a new rain tent.

The same tracking numbers are used by both DHL and USPS. I didn’t know USPS would be delivering beforehand, I only found out through one of the DHL updates. Your delivery may use different vendors. Only the accessories arrived via USPS; the bicycle arrived in three boxes directly from DHL.

It took 18 and 19 days for accessories to arrive, and 24 days for the bicycle itself.

Here are the data on shipping to East Grand Forks, MN (dates with no news are included so you can see the pace of updates).

  • Day 0 (2018-02-09)
    • Order submitted
  • Day 1
    • Received email confirmation of order, saying “2 to 3 weeks for delivery”
  • Day 2
  • Day 3
    • Email from DHL with two tracking numbers (Package 1 and Package 2), but comment only mentioned toddler seat.
  • Day 4
  • Day 5
  • Day 6
    • Package 1 processed in Dorsten, Germany
    • Package 2 processed in Dorsten, Germany
  • Day 7
    • Package 1 processed in Rodgau, Germany
    • Package 2 processed in Rodgau, Germany
    • Package 1 at the airport IPZ-Ffm, Germany
    • Package 2 at the airport IPZ-Ffm, Germany
  • Day 8
  • Day 9
  • Day 10
  • Day 11
  • Day 12
    • Package 2 processed in ISC CHICAGO IL (USPS)  
  • Day 13
    • Package 2 Inbound Out of Customs 
  • Day 14
    • Package 1 processed in ISC CHICAGO IL (USPS) 
    • Email from MAB: “Next week you will receive your tracking and the  estimated delivery date. I expect your bike to be delivered end of next week, or maybe beginning of the week after.”
  • Day 15
    • Package 1 Inbound Out of Customs 
    • Package 1 Arrived at USPS Regional Facility CHICAGO IL INTERNATIONAL DISTRIBUTION CENTER
  • Day 16
    • Package 1 In Transit to Next Facility 
  • Day 17
    • Package 1 In Transit to Next Facility 
    • Package 2 Arrived at USPS Regional Destination Facility WEST FARGO NETWORK DISTRIBUTION CENTER (note that Package 2 skipped Chicago USPS…)
  • Day 18
    • Package 2 Arrived at USPS Regional Destination Facility GRAND FORKS ND DISTRIBUTION CENTER 
    • Package 2 Sorting Complete EAST GRAND FORKS, MN 56721
    • Package 1 In Transit to Next Facility (it’s weird how this package has very little detail about where it is, just that it’s moving)
    • Package 2 Out for Delivery EAST GRAND FORKS, MN 56721  
    • Package 2 delivered
  • Day 19
    • Package 1 Arrived at USPS Regional Destination Facility GRAND FORKS ND DISTRIBUTION CENTER  
    • Package 1 Arrived at Unit GRAND FORKS, ND 58201
    • Package 1 Sorting Complete EAST GRAND FORKS, MN 56721 
    • Package 1 delivered
    • I emailed to ask about the bike tracking number, since both packages I knew about had arrived.
  • Day 20 (2018-03-01)
    • Email from MAB: “The bike will be shipped this week (I think today) and will send you the tracking number as soon as receive it from the shipping company”
  • Day 21
    • DHL shipment created for Package 3 (rain tent for City)
  • Day 22
  • Day 23
  • Day 24
    • With no tracking code ever delivered to me, the bicycle arrives in a DHL van! So it was delivered according to the email way back on Day 14. Of note, DHL delivered during a snowstorm so I was actually home (actually outside shoveling) and able to sign for it. Not sure if they would have left the boxes otherwise.

 

 

Rainmeter Snow Skin for JohnDee.com

Snow map from JohnDee.com.

JohnDee.com has some pretty neat maps, but the URL structure is dynamic, so this one is a little more complicated than my previous skins. Enjoy!

Update: I’m not sure why this isn’t refreshing automatically, but manually refreshing the skin must reload the variables.

;Shows the 4-day snowfall prediction from JohnDee.com.
;Much help from https://www.reddit.com/r/Rainmeter/comments/2qjbpw/help_build_url_by_concatenating_text_date_time/cn99at7/

[Rainmeter]
Update=3600
;To make this to immediately show up, change value to 0 and refresh.

[MeasureDateY]
Measure=Time
Format=%Y

[MeasureDateM]
Measure=Time
Format=%m

[MeasureDateD]
Measure=Time
Format=%d

[MeasureURL]
Measure=String
String=http://johndee.com/wp-content/uploads/[MeasureDateY]/[MeasureDateM]/MIDSNOW[MeasureDateM][MeasureDateD].jpg
DynamicVariables=1

[MeasureImage]
Measure=Plugin
Plugin=WebParser
MeasureName=MeasureURL
URL=[&MeasureURL]
Download=1

[MeterImage]
Meter=Image
MeasureName=MeasureImage
H=375
W=500

Campus Size Comparison

This keeps popping into my head, so I finally looked at it. St. Lawrence University is a walking campus (parking only available on fringes), while UND allows parking within campus (and car culture is deeply ingrained).

How similar/dissimilar are the campus sizes? See for yourself with the below animation, maps at same scale (click for larger).

Sources:

 

sum() with raster::aggregate() in R

If you try to use sum() directly in raster::aggregate() and have NA values, you’ll get NA as a result. You need to build a tiny function and pass the rm.na=T command to sum(). More succintly:

# Dissolve duplicate geometries and sum OOIP
 fm <- raster::aggregate(fm.raw,
                         by="OilFieldID",
                         sums=list(list(function(x) sum(x,na.rm=T),
                                        "OOIP_pooltable")))