Handyhalterung aus PET
Mein VW New Beetle hat werkseitig eine Handyvorbereitung … dafür gibt es für mehr oder weniger viel Geld auch Schalen, die man da reinklipsen kann … die dann das jeweilige Handy aufzunehmen versprechen.
Aber dafür jetzt nochmal Münzen einwerfen, zumal gut alle Jahr eh ein neues Handy folgt … weiß nicht. Und Fablab heißt ja auch selber machen.
Also OpenSCAD angeworfen und eine Handyhalterung gezeichnet, die einerseits mein Samsung Galaxy S5 aufnimmt und andererseits dem Clips-Mechanismus von VW genügt:
… das ganze dann auf den 3D Drucker gejagt. Als Filament habe ich PET verwendet — im Gegensatz zu PLA sollte das auch der direkten Sonneneinstrahlung im Auto längere Zeit trotzen. Und die Transparenz macht sich schon auch irgendwie gut …
Einige Fehlversuche später lässt sich das Ergebnis im Auto dann auch ansehen.
Learning des Abends: Wenn man im Cura eine „Pause at Z“ einstellt, dann die Parkposition niemals auf 0 / 0 stellen. Das führt dazu, dass der Druckkopf satt vorne links an den Anschlag läuft :-/ … zwar nicht mehr weit, sodass nicht wirklich was passiert (außer dass die Stepper Schritte verlieren und der Ausdruck dadurch Müll ist), aber trotzdem ein Schreckmoment …
php.net account approved
After waiting for a really long time (half a year) I finally have an approved php.net + PECL account granted with lead-rights on V8Js :-)
… therefore I finally published V8Js version 0.2.0, succeeding 0.1.5 which was published 1.5 years ago.
Changes include
- adapt to latest v8 API (v8 versions from 3.24.6 up to latest 4.3 branch supported now)
- v8 debugging support
- apply time & memory limits to V8Function calls
- support mapping of PHP objects implementing ArrayAccess to native arrays
- new API to set limits: setTimeLimit & setMemoryLimit methods on V8Js object
- typesafe JavaScript function wrappers
- improved back-and-forth object passing (rewrapping, correcty isolate unlocking)
- fix property and method visibility issues
- fix memory leaks
Download the release from PECL repository.
Nervenfräse
Bernd war heute da und irgendwann kam die Idee auf, die CNC zu nutzen um seinen nickname auf einen USB-Stick zu gravieren.
Gesagt, versucht, gescheitert. Die Idee war zunächst mit Inkscape den Schriftzug zu erstellen und den Pfad als G-Code zu exportieren. PyPC-NC hat den Schriftzug ein bisschen verstümmelt:
Wie sich beim Debuggen zeigte war die Polar-Koordinaten gestützte Korrektur noch nicht fehlerfrei. Nach einigen Versuchen sah es dann deutlich besser aus:
… der letzte Versuch mit einem Streckfaktor von zwei und phi von 45°.
Polar-korrigiertes Fräsen und Bohren
… immer noch auf dem Weg zur selbst erstellten Platine, genauer gesagt beim Bohren eben dieser. Kürzlich bin ich noch über das Problem gestoßen, dass man die Platine exakt gerade in die Fräse einlegen muss, dass die Bohrlöcher auch an der richtigen Stelle im Epoxyd landen und nicht etwa ein paar Millimeter daneben. Das ist aber gar nicht so einfach …
… die „Softie“-Lösung, bevor ich mir Mühe mit der „Hardware“ geb‘, arbeite ich doch lieber mit Software um das Problem herum.
Gegeben sei also eine Platine (hier eine „Simulation“ in Form eines simplen A4-Blatts), die nicht exakt gerade in der Fräse liegt, etwa so:
… dann muss man dem Controller der Fräse nur noch beibringen, wo zwei frei gewählte Punkte aus dem G-Code in der Realität liegen. PyPC-NC ermittelt daraus mittels Polarkoordinaten dann zwei Korrekturwerte: um wieviel Grad muss gedreht werden und um welchen Faktor ist der Radius zu korrigieren.
… bei der Gelegenheit ist für PyPC-NC eine grafische Darstellung des G-Codes auf der XY-Plane abgefallen nebst der Möglichkeit den Ursprung der G-Code Datei nach belieben fest zu legen.
PyPC-NC … oder: ich will auch mal mit der CNC spielen
Zugegebenermaßen hat mich der CNC-Tisch in unserem Fablab schon eine ganze Weile gereizt, wenn nicht schon von Anfang an. Vor guten zwei Wochen kam mir dann die Idee, nachdem ich in den Schränken 7-Segment-Anzeigen in rauen Mengen liegen sah, mal wieder ein bisschen mit Elektronik zu basteln … und da war noch das leidige Thema mit den Platinen … aber wir haben jetzt ja diesen Tisch und da müsste doch was gehen …
Also, Tisch ansteuern. Aber so einfach ist das nicht, zumindest wenn man nicht die Windows-Software nutzen möchte, von der wir ohnehin nur eine einzige Lizenz haben. Paul hatte sich hieran ja auch schon versucht, vgl. ältere Posts hier im Blog, … aber sein Projekt ist groß angelegt (er möchte ja einen Großteil der Ansteuerungselektronik des Tisches ersetzen) und wird noch eine ganze Weile bis zur Fertigstellung brauchen.
Eine andere Lösung musste her; der Tisch selbst hat ja einen Achscontroller integriert, warum also nicht den nutzen? Schließlich hat der auch relativ intelligente look-ahead Funktionen eingebaut, etc., also bringt’s auch durchaus Vorteile den zu lassen … nur spricht die Windows-Software ihr eigenes Protokoll mit dem Achscontroller, das alles andere als standardisiert und offen ist.
Aber egal, Fablab heißt ja „selber machen“, los ging’s also letzte Woche Samstag beim Osterbasteln, erste Gehversuche wie man den Achscontroller ansteuert und das Protokoll zu einem großen Stück reversed. Genau geguckt, gelernt, nachmachen, … Software schreiben. In Anlehnung an das Windows-Programm WinPC-NC wurde PyPC-NC geboren, die freie Alternative in Python, … primär für Linux:
… so sieht’s aus :-)
Optisch nicht gerade ein Leckerbissen, aber funktional und kann soweit alles was man braucht. Automatische Referenzfahrt, manuelles Fahren zu einer beliebigen Position, diese als Werkstückposition speichern und G-Code importieren um „Fahr-Programme“ aus anderen Anwendungen zu übernehmen.
In Kombination mit den Linux Anwendungen „gEDA“ und „PCB“ kann man sich dann ein Platinenlayout entwerfen und via G-Code Export an PyPC-NC übergeben. Das Ergebnis findet sich hier im Bild rechts (wobei in den Tisch eine 08/15 Kugelschreibermine eingespannt war).
Links sieht man erste Fräsversuche auf einer Leiterplatine, ein paar waren zu tief, manche Bahnen sind echt gut gelungen.
Der Teufel steckt wie so häufig im Detail, aktuell gibt’s noch das Problem, dass das Brett, das als Unterlage im CNC-Tisch liegt sowie die Platine selbst leicht gebogen sind, … ungünstig wenn man die Platine im 1/100-tel Millimeter-Bereich genau anfährt. Mal sehen, kriegen wir auch noch gelöst :-)
Ein Opfer gibt es leider jedoch bereits zu beklagen:
… dieser Fräsbohrer musste wegen einem Bug in der Software sein Leben lassen. In X-Richtung wurde dieser blöderweise fünfmal so schnell angefahren wie gewollt … das war dann wohl zu viel Druck :-/
… wir brauchen bald wohl auch einen Satz neue Bohrer …
New Project: Ingressors
After my colleage Tino Dietel and I came up with the idea of a web application providing a web of trust among local Ingress Resistance agents, I actually started to get my hands dirty somewhen last week. I labeled my newest pet project ingressors. The source code is already available from GitHub
Ingressors is a web application based on the Locomotive.js MVC framework by Jared Hanson. This is the application sits on a Node.js+Express.js stack and uses Neo4j as its backing service. The frontend itself is page-load driven and makes use of Bootstrap by Twitter.
So far the application allows to
- authenticate via OAuth against Google+ (uses Passport middleware)
- store ingress nickname and Google+ reference to Neo4j store
- poke other agents
- reject or accept pokes (where accept means you trust another agent)
- list incoming and outgoing trust
- display a web of trust in list form, i.e. a list of agents you trust, agents trusted by agents you trust, agents trusted by agents trusted you trust, etc.pp. The table also shows the number of incoming trusts for each agent.
I decided to not host the application by myself, but try out hosting on Heroku instead. Heroku is a cloud platform as a service, that allows hosting of apps written in Node.js, Python Django and others. Hosting there is free of charge as long as the app uses only a single Dyno (frontend server instance). Neo4j is available as an add-on, however without a Gremlin stack – but Cypher queries are more than enough for this new app :-)
Update: I never really published nor completed the application. After all I even lost interest in Ingress some time ago.
Geierlein's import interface
From version 0.5.2 on Geierlein now has an import interface, which I came up while discussing issue #19. Initially Peter wanted to know whether and how it is possible to load form data from disk from within the web interface, since there were neither buttons nor a menu allowing to do so (opposed to the XUL-backed frontend, which has already been providing this freature from the initial release on).
During the discussion it turned out, that what Peter really wanted to do was integrating Geierlein with a web-based ERP system. Having the ERP system export a file (via download) and then uploading that particular file into Geierlein seemed cumbersome, hence I was looking for a clean interface between the two.
As Geierlein is a fully client-side application, that fetches just a single HTML file
along with a bunch of JavaScript files, data passing has to be fully client-side
as a consequence. This is the data cannot just be POSTed (which would transmit the data
to the webserver) or so. Either it has to be provided by a local means like
localStorage
or Geierlein has to actively fetch the data from elsewhere (the calling
application), which leads to authentication issues in turn.
According to Peter Kivitendo ERP has
no Ajax layer or REST API, from which the data could be fetched, hence it
would be a lot of work on that side, if Geierlein would insist on actively fetching
the data. Therefore I went the local data passing route and implemented both,
data passing via localStorage
and window.name
.
This is any calling application can store data in Geierlein file format into
the localStorage
object and forward to Geierlein providing a special hash like
so:
localStorage["geierlein.import"] = "\
name = Stefan Siegl\n\
strasse = Philipp-Zorn-Str. 30\n\
plz = 91522\n\
ort = Ansbach\n\
land = 2\n\
steuernummer = 123/123/12345\n\
jahr = 2013\n\
zeitraum = 5\n\
kz81 = 1000\n\
kz89 = 500\n\
kz83 = 285,00\n";
location.href = "http://localhost:4080/#importLocalStorage";
The special hash triggers an import routine in Geielein, which reads the key from the storage object, fills the form accordingly, clears the storage and adds a notice to the begining of the page, that the import has taken place successfully. The calling application can not directly trigger data transmission of any sort. The user of Geierlein always has the ability to review the data and finally has to click the send button (and fill her signature credentials).
As access to local storage is restricted by the Same-Origin-Policy there is no risk of leaking data to external sites, however it is required, that the data providing application (like Kivitendo ERP) and Geierlein are installed under the same domain.
If that is not possible, data can be passed via window.name
. This however
has the problem of possibly leaking data, if the calling application (ERP)
is not configured correctly and forwards to a third-party site instead of
Geierlein.
Anyways, to pass form data to Geierlein using window.name
, the example from
above just has to be modified slightly:
- data must obviously be stored to
window.name
instead - the hash needs to be
#importWindowName
v8js patches merged
Today the last pull request in a series of contributions to the V8Js PHP extension has been merged. Good time to loose some words on the project and why I like it, so here we go :-)
V8Js is a PHP extension that integrates Google’s V8 JavaScript engine into PHP. This is the extension allows you to execute JavaScript code securely sandboxed from PHP. Besides it allows for simple exchange of data from PHP to JavaScript and back.
I like V8Js as it allows to run customer-provided code on the server, knowing that it is properly sandboxed so it cannot interact with all your PHP classes, variables and whatnot. Instead you can (and have to) provide a restricted set of classes acting as an API the JavaScript code can use.
First things first, a simple hello world:
$a = new V8Js();
$a->executeString('print("Hello World\n");');
… super simple and doesn’t do very much.
Of course you can inject object instances as well:
class LoaderWriter {
public function addRecord($type = 'text', $value = '') {
echo "addRecord -- $type, $value\n";
}
}
$jscode = <<< EOT
PHP.loader.addRecord("text", "first loader insert");
EOT;
$a = new V8Js();
$a->loader = new LoaderWriter();
$a->executeString($jscode);
However that’s still stuff you’d expect to work. What about pushing closures from JavaScript to PHP and call these from PHP? Works!
class Parser {
protected $_callbacks = array();
public function on($element, $callback) {
$this->_callbacks[$element] = $callback;
}
public function runParser() {
// should be fleshed out of course :-)
$this->_callbacks['node']('node-1 content');
$this->_callbacks['node']('node-2 content');
}
}
$jscode = <<< EOT
PHP.parser.on("node", function(data) {
print("Found node, content " + data + "\n");
});
EOT;
$a = new V8Js();
$a->parser = new Parser();
$a->executeString($jscode);
$a->parser->runParser();
… this way you can easily use PHP’s nice XmlReader to read chunks from XML files and have a customer-provided piece of JavaScript code bind on certain elements to drive customer-fitted data imports.
The code just does what you expect, it initializes a parser class, binds an element handle (which is a JavaScript function) and afterwards the parser (written in PHP) just calls the callback function transparently. And of course it’s not just possible to provide scalar values back and forth, you can pass objects just as transparently.
Turned out that V8Js leaked some memory for each object being passed back to JavaScript, which doesn’t hurt much if you do it for a limited number of times. If you run the callback from above for a huge XML file you’re quickly hit. The problem was, that V8Js incremented the refcount on the PHP object, but didn’t decrease if V8 decided to dispose the JavaScript instance. The fix for this is merged since July 11th.
Officially the PECL package is still in beta state and I found some bugs after a limited number of evaluation hours … if you can live with that I think V8Js is a pretty cool sandbox environment, definitely worth a look.
Since I’ve made myself familiar with the source I also replaced deprecated calls to V8 API by newer equivalents and allowed for construction of PHP objects from JavaScript. This is do stuff like that:
$v8 = new V8Js();
class Greeter {
function sayHello($a) {
echo "Hello $a\n";
}
}
$jscode = <<< EOT
PHP.greeter.sayHello("John");
// prints "Hello John" as expected
print(PHP.greeter); print("\n");
// prints "[object Greeter]" as expected
// What about the constructor function of greeter?
print(PHP.greeter.constructor);
// ... yields "function Greeter() { [native code] }"
// ... super, so let me create more greeters :-)
var ngGreeter = new PHP.greeter.constructor();
ngGreeter.sayHello("Ringo");
// well, ... used to segfault :-)
EOT;
$v8->greeter = new Greeter();
$v8->executeString($jscode);
… I can’t immediately come up with a use case, but hey, JavaScript is all about (constructor) functions, so it definitely should work. And of course it shouldn’t be possible to crash the sandbox :-)