Multiple Raspberry Pi Zero g_ether gadgets.
Posted: October 4, 2016 Filed under: Raspberry Pi Leave a commentMy notes for connecting multiple pi zero nodes to a single pi 2/3 host.
See the e.g. notes, for each node we will be incrementing the host names, mac addresses, and ip subnets.
On the host.
Enable ipv4 forwarding and iptables NAT.
Run ssh-keygen to create and populate the ~/.ssh folder.
For each node.
Add entry to /etc/udev/rules.d/90-cluster.rules.
(e.g. use 00:22:82:ff:ff:02 and ethpi2 for the next one.)
SUBSYSTEM=="net", ATTR{address}=="00:22:82:ff:ff:01", NAME="ethpi1"
Add entry to /etc/network/interfaces.
(e.g. use ethpi2, 10.0.2.100, 10.0.2.0 and 10.0.2.255 for the next one.)
allow-hotplug ethpi1 iface ethpi1 inet static address 10.0.1.100 netmask 255.255.255.0 network 10.0.1.0 broadcast 10.0.1.255
On each node.
Use raspi-config to change the hostname and expand the file system.
Run ssh-keygen to create and populate the ~/.ssh folder.
Append the host machines ~/.ssh/id_rsa.pub to the nodes ~/.ssh/authorized_keys
Add modules to /boot/cmdline.txt on the same line after rootwait.
(e.g. use 00:22:82:ff:ff:02 and 00:22:82:ff:ff:12 for the next one.)
modules-load=dwc2,g_ether g_ether.host_addr=00:22:82:ff:ff:01 g_ether.dev_addr=00:22:82:ff:ff:11
Add overlay to bottom /boot/config.txt.
dtoverlay=dwc2p
Add entry to bottom of /etc/dhcpcd.conf
(e.g. use 10.0.2.10 and 10.0.2.100 for the next one.)
interface usb0 static ip_address=10.0.1.10 static routers=10.0.1.100 static domain_name_servers=8.8.8.8
Digital Ocean – Remote Desktop – What $5 a month buys you.
Posted: October 18, 2015 Filed under: Uncategorized Leave a commentGo sign up at Digital Ocean and create a 512MB RAM, 1 CPU droplet in your region using the Ubuntu image.
Wait a whole dammed minute for your 20 GB SSD based VM to be provisioned and go get your root credentials from the welcome email.
If you manage your own DNS, which you must or we can’t hangout, go add an A record for the VM IP like with coolname.yourdomain.huh.
SSH into the box and change your password and maybe apt-get update, apt-get -y upgrade, reboot. No sudo required. Whoami, I am root beaches, this is free balling.
Then apt-get install -y lxde xrdp midori. Remote in with mstsc or rdesktop to your hearts content and use it like a shoe, like for if your work blocks eBay and that is basically your second income.
Add swap as needed, you will need it.
I only do all this so I can run byobu, mwahahahaha.
SQL SMO PowerShell
Posted: May 12, 2013 Filed under: Uncategorized Leave a commentSome simple PS that has potential.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Just some shortcuts on top of SMO to add powershell flavor. | |
| Basically you pick from a collection, and choose an item, rinse and repeat. | |
| Easier done than said. | |
| Note: Be careful with this, you are on top of SMO and that can kill things. | |
| Note: Piping any SMO object at all to Export-Clixml looks interesting. | |
| TODO: Needs more documentation. | |
| TODO: Add script options. | |
| TODO: Add depends function with the dependency walker stuff. | |
| TODO: Consolidate pick and choose function, make it smarter. | |
| e.g. | |
| (express).Databases | pick Northwind | choose Tables | list | |
| (express).Databases | pick Northwind | choose Tables | pick Suppliers | script | |
| (express).Databases | pick Northwind | choose Tables | pick Suppliers | Select-Object -Property Columns | |
| (express).Databases | pick Northwind | choose Views | owner dbo | list |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null; | |
| function express() { | |
| server ".\sqlexpress" | |
| } | |
| function server($name) { | |
| New-Object Microsoft.SqlServer.Management.Smo.Server $name | |
| } | |
| function list() { | |
| $input | Select-Object -Property Name | |
| } | |
| function pick($name) { | |
| $input | Where-Object {$_.Name -eq $name} | |
| } | |
| function choose($name) { | |
| $input | Select-Object -ExpandProperty $name | |
| } | |
| function owner($owner) { | |
| $input | Where-Object {$_.Owner -eq $owner} | |
| } | |
| function script() { | |
| $input | ForEach-Object {$_.Script()} | |
| } |
Sample dependency injection for suburbanites
Posted: May 11, 2013 Filed under: Uncategorized Leave a commentProgrammers write a whole lot of code to use to “spin up” other objects in order to use that objects services and all of the required dependencies to use the object services are otherwise of absolutely no concern to the consumer of the service. It is pernicious. See Separation of concerns for more info.
The factory may seem like a lot of work and a lot of code but most times you don’t code it and it is generated, either at compile time, perhaps using attributes for some aspect oriented programming, or at runtime using reflection. In the end whatever work you put into configuring it is supposed to be recouped by all the supposedly many consumers who no longer have to open their garage door and rummage about for two stroke oil.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // All I want is my lawn mowed. | |
| // Yet I have to gather up the tools which are of no direct use to me in this case. | |
| var myLawn = {}, myWalk = {}; | |
| var myTools = MyGarage.Tools(["mower", "gas", "oil", "broom"]); | |
| var gardener = new Gardener(myTools); | |
| gardener.mow(myLawn); | |
| //Given the factory code below now all I have to do is this. | |
| var worker = workerFactory().getWorker("gardener") | |
| worker.mow(myLawn); | |
| worker.sweep(myWalk); | |
| var workerFactory = function() { | |
| map = { | |
| gardener : { | |
| tools : ["mower", "gas", "oil", "broom"], | |
| skills : {mow: function(lawn) {return "yes boss";}, sweep: function(walk) {return "yes boss";}} | |
| } | |
| } | |
| function getWorker(type) { | |
| var worker = {type: type}; | |
| // Give the worker tools | |
| var tools = map[type].tools; | |
| worker.tools = []; | |
| for (var item in tools) { | |
| worker.tools[item] = tools[item]; | |
| } | |
| // Give the worker skills | |
| var skills = map[type].skills; | |
| for (var item in skills) { | |
| worker[item] = skills[item]; | |
| } | |
| return worker; | |
| } | |
| return { | |
| getWorker: getWorker | |
| } | |
| } |
Breeze and knockout quick start.
Posted: May 8, 2013 Filed under: .NET, JavaScript | Tags: breeze, knockout Leave a commentAn attempt at a bare minimum to get breeze and knockout going.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Create a new MVC4 web application web api project. This will bring in jQuery and knockout. | |
| Nuget install-package Breeze.WebApi. | |
| Add a dbcontext class in Models and a breeze api controller in Controllers. | |
| Add an html page with a view model and a view. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Linq; | |
| using System.Web.Http; | |
| using Breeze.WebApi; | |
| using MvcApplication1.Models; | |
| using Newtonsoft.Json.Linq; | |
| namespace MvcApplication1.Controllers | |
| { | |
| [BreezeController] | |
| public class FooController : ApiController | |
| { | |
| private readonly EFContextProvider<FooData> _ctx = new EFContextProvider<FooData>(); | |
| [HttpGet] | |
| public string Metadata() | |
| { | |
| return _ctx.Metadata(); | |
| } | |
| [HttpGet] | |
| public IQueryable<Foo> Foos() | |
| { | |
| return _ctx.Context.Foo; | |
| } | |
| [HttpPost] | |
| public SaveResult SaveChanges(JObject saveBundle) | |
| { | |
| return _ctx.SaveChanges(saveBundle); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Data.Entity; | |
| namespace MvcApplication1.Models | |
| { | |
| public class Foo | |
| { | |
| public int Id { get; set; } | |
| public String Name { get; set; } | |
| } | |
| public class FooData : DbContext | |
| { | |
| public DbSet<Foo> Foo { get; set; } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html xmlns="http://www.w3.org/1999/xhtml"> | |
| <head> | |
| <title></title> | |
| <script src="Scripts/jquery-1.8.2.min.js"></script> | |
| <script src="Scripts/knockout-2.2.0.js"></script> | |
| <script src="Scripts/q.min.js"></script> | |
| <script src="Scripts/breeze.min.js"></script> | |
| <script type="text/javascript"> | |
| var mgr = new breeze.EntityManager("breeze/Foo"); | |
| var Vm = function () { | |
| var items = ko.observableArray(); | |
| var item = ko.observable(); | |
| mgr.executeQuery(breeze.EntityQuery.from("Foos")) | |
| .then(function (val) { | |
| val.results.forEach(function (result) { | |
| items.push(result); | |
| }); | |
| }); | |
| function add() { | |
| items.push(mgr.createEntity("Foo", { Name: item() })); | |
| mgr.saveChanges(); | |
| item(""); | |
| } | |
| function remove(data) { | |
| data.entityAspect.setDeleted(); | |
| mgr.saveChanges(); | |
| items.remove(data); | |
| } | |
| return { | |
| items: items, | |
| item: item, | |
| add: add, | |
| remove: remove | |
| }; | |
| }; | |
| $(function () { | |
| ko.applyBindings(new Vm()); | |
| }); | |
| </script> | |
| </head> | |
| <body> | |
| <form data-bind="submit: add"> | |
| <input type="text" data-bind="value: item" /> | |
| <input type="submit" value="add" /> | |
| </form> | |
| <div data-bind="foreach: items"> | |
| <span data-bind="text: Name"></span> | |
| <input type="button" value="delete" data-bind="click: $parent.remove" /> | |
| <br /> | |
| </div> | |
| </body> | |
| </html> |
Knockout with jQuery UI
Posted: April 28, 2013 Filed under: JavaScript | Tags: jQuery UI, knockout.js 3 CommentsSample code to demonstrate trivial edits using knockout.js and jQuery UI dialog.
The main things to note are that all item properties are observable, and changes to an observable’s properties can be undone. Depends on Popup.js.
Updated to include localStorage. And to add another property to the model with no muss no fuss.
<head runat="server">
<title></title>
<link href="Content/themes/base/jquery.ui.all.css" rel="stylesheet" />
<script src="Scripts/jquery-2.0.0.min.js"></script>
<script src="Scripts/jquery-ui-1.10.2.min.js"></script>
<script src="Scripts/knockout-2.2.1.js"></script>
<script src="Scripts/knockout.mapping-latest.js"></script>
<script src="Scripts/Popup.js"></script>
<script type="text/javascript">
$(function () {
ko.applyBindings(new ViewModel);
});
function Storage(ctor) {
// Class to handle local storage for observable array with observable item properties.
function load() {
var items = [] // Something to return.
var data = JSON.parse(localStorage.getItem(ctor.name));
if (data) {
data.forEach(function (item) {
var obj = new ctor(); // Spin up one of what was specified.
$.extend(obj, item); // Pound in the properties.
items.push(ko.mapping.fromJS(obj)); // Make all properties live and push it.
});
}
return items;
}
function save(value) {
var items = [] // Something to save.
value.forEach(function (item) {
items.push(ko.mapping.toJS(item)); // Strip off the KO decor.
});
localStorage.setItem(ctor.name, JSON.stringify(items)); // Stringify it and save it.
}
// Return this interface.
return {
load : load,
save : save
};
}
function Statefull() {
// Class to handle saving and restoring observable properties.
var self = this; // Hang onto this to prevent ambiguity later on.
var state = []; // Empty bag to hold properties.
function backup() {
// Clear the array and add items to the bag.
state = [];
for (var prop in this) {
// Add only "descendant" properties that are observable.
if (!self.hasOwnProperty(prop) && ko.isObservable(this[prop]))
state.push({ name: prop, value: this[prop]() });
}
};
function restore() {
// Replace values with saved ones.
state.forEach(function (prop) {
this[prop.name](prop.value);
}, this);
};
// Return this interface.
return {
backup: backup,
restore: restore,
};
}
function Contact() {
// Plain old property bag.
this.firstName = "";
this.lastName = "";
this.email = "";
};
function ViewModel() {
// Class to handle adding and editing items.
// Uses jQuery UI dialog and KO bindings.
Contact.prototype = new Statefull; // Make Contact Statefull
var storage = new Storage(Contact); // localStorage thingy.
function newItem() {
// Create scratch object where all properties are observable.
return (ko.mapping.fromJS(new Contact));
};
function clearItem() {
// Clear out the item being tracked.
thing(newItem());
};
function add() {
// Opens the dialog to allow a new item to be added.
// Saves the item when OK button is pressed.
clearItem(); // Set the tracked item to be a new item.
popup.show(
{
ok: function () {
things.push(thing()); // Add the new item.
storage.save(things()); // Save all things.
clearItem(); // Clear the tracked item.
}
}, { title: Popup.Strings.New }
);
};
function edit(item) {
// Opens the dialog to allow an existing item to be modified.
item.backup(); // Save the items state.
thing(item); // Set tracked item to the exisitng item.
popup.show({
ok: function () {
storage.save(things()); // Save all things.
},
cancel: function () {
item.restore(); // on Cancel restore the items state.
}
}, { title: Popup.Strings.Edit }
);
};
// Set up working variables.
var popup = new Popup("#edit"); // Tie in the dialog.
var thing = ko.observable(newItem()); // The tracked item.
var things = ko.observableArray(storage.load()); // All items.
// Return this interface.
return {
thing: thing,
things: things,
add: add,
edit: edit
};
};
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div data-bind="with: thing" id="edit">
First: <input type="text" data-bind="value: firstName" />
Last: <input type="text" data-bind="value: lastName" />
Email: <input type="text" data-bind="value: email" />
</div>
<button data-bind="click: add">Add</button>
<div data-bind="foreach: things">
<span data-bind="text: firstName"></span>
<span data-bind="text: lastName"></span>
<span data-bind="text: email"></span>
<a href="#" data-bind="click: $parent.edit">edit</a>
<br />
</div>
</div>
</form>
</body>
What is this and why use new?
Posted: April 28, 2013 Filed under: JavaScript | Tags: constructor, javascript, new Leave a commentGiven the function.
var foo = function(name) {this.name = name; return this;}
This code may not do what one might think it does.
var a = foo("a"); a.name;
var b = foo("b"); b.name;
a.name;
You can kind of see why by checking out what these return.
foo("a");
new foo("a");
This however works as one might expect.
var a = new foo("a"); a.name;
var b = new foo("b"); b.name;
a.name;
RE: Way to Lambda
Posted: January 5, 2013 Filed under: .NET | Tags: .NET, Lambda, Linq Leave a commentOne use of lambdas is to provide a method to a sub-routine that it can call if it needs something from the caller. I have implemented this pattern in a temporary caching class that I use sometimes but I think this example is more fun.
using System;
using System.Collections.Generic;
public class CowBell { }
public class BlueÖysterCult
{
public BlueÖysterCult()
{
var session = new JamSession<CowBell>();
session.Jam(
needs: () => session.TheCure.Count < 1000,
more: () => new CowBell());
}
}
public class JamSession<T>
{
public List<T> TheCure;
public JamSession()
{
TheCure = new List<T>();
}
public void Jam(Func<Boolean> needs, Func<T> more)
{
while (needs())
{
TheCure.Add(more());
}
}
}
And if that is not a big enough of a yawn, here is a simple generic cache implementation.
public class Cache<T> where T : class
{
private readonly Func<string, object> _get;
private readonly Action<string, object> _set;
private readonly Action<string> _clear;
private readonly Func<string> _name;
public Cache()
{
_get = (key) => HttpContext.Current.Cache[key];
_set = (key, obj) => HttpContext.Current.Cache[key] = obj;
_clear = (key) => HttpContext.Current.Cache.Remove(key);
_name = () => typeof (T).FullName;
}
public T Item
{
get { return (T)_get(_name()); }
private set
{
if (value == null) _clear(_name());
else _set(_name(), value);
}
}
public T Get(Func<T> data)
{
return Item ?? (Item = data());
}
public void Clear()
{
Item = null;
}
public bool Exists()
{
return Item != null;
}
}
Generic DbContext with REST methods
Posted: December 27, 2012 Filed under: .NET | Tags: ApiController, DBContext Leave a commentSimple generic wrapper to put CRUD on top of a class to use for a Web API or for data binding.
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
/// <summary>
/// Bit bucket class
/// </summary>
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
/// <summary>
/// Generic RESTish dbcontext.
/// </summary>
public class ContactContext : codewarren.com.SimpleContext<Contact> { }
namespace codewarren.com
{
/// <summary>
/// Class that puts generic REST type methods on top of a class.
/// </summary>
/// <typeparam name="T"></typeparam>
public class SimpleContext<T> : DbContext where T : class
{
public DbSet<T> Items { get; set; }
public List<T> Get()
{
return Items.ToList();
}
public T Get(int id)
{
return Items.Find(id);
}
public void Put(T item)
{
Items.Attach(item);
Entry(item).State = EntityState.Modified;
SaveChanges();
}
public void Post(T item)
{
Items.Add(item);
SaveChanges();
}
public void Delete(int id)
{
Delete(Get(id));
}
public void Delete(T item)
{
Items.Attach(item);
Entry(item).State = EntityState.Deleted;
SaveChanges();
}
}
}
Here is a ApiController that makes use of it.
using System.Collections.Generic;
using System.Web.Http;
public class GenericController<T> : ApiController where T: class
{
private readonly SimpleContext<T> _context = new SimpleContext<T>();
public List<T> Get()
{
return _context.Get();
}
public T Get(int id)
{
return _context.Get(id);
}
public void Post([FromBody]T t)
{
_context.Post(t);
}
public void Put([FromBody]T t)
{
_context.Put(t);
}
public void Delete(int id)
{
_context.Delete(id);
}
}
public class ContactController : GenericController<Contact> {}
AppHarbor Quick Start
Posted: August 4, 2012 Filed under: .NET | Tags: .NET, AppHarbor, CI Leave a commentAppHarbor is a cloud based an online continuous integration service. It takes a commit to source code version control repository, builds it and deploys it to a host.
What this provides is fast web application deployment that includes hosted change management and site hosting.
In this example we will use a GitHub repository and it’s Windows client so that needs to be installed first.
Login to AppHarbor and create a new application.
On the application page choose the option to Configure GitHub to deploy to AppHarbor. This will let you choose to create a new repository or use an existing one.
Login to GitHub and add the repository to the Windows client. Search for the repository by name in the form of AppHubUserName/GitHubRepositoryName. Click the button to Setup In Windows and it will launch the GitHub Windows client.
In the GitHub client you can open the repository in Windows explorer and add files using any tool including creating a new ASP.NET web site there in the existing location using Visual Studio.
After creating the files return to the GitHub client, and a comment, commit the changes then publish the changes to the server. In AppHarbor on the application page you will see the commit and from there you can click the link to Go to your application to see the site hosted on the web.
Note that repositories can be shared with other GitHub Windows users with a URL like:
github-windows://openRepo/https://github.com/userName/repoName