LEGO Lighting kits seem to be getting more popular these days so when Lightailing reached out to me to see if I was interested in picking one of their lighting kits to review I jumped at the chance. We had not too long ago finished building theLEGO Treehouse (21318), we thought it was the perfect set to upgrade with Lightailing’s amazing lighting kit.
The kit arrived in a smaller box than I expected, they have done a great job making the packaging look very clean and professional whilst maintaining a strong box to protect your lighting kit.
Contents
Now we get to the bit you are waiting for, the contents!
19 sealed bags with the lighting components within
The “paperwork” is presented in a thick poly bag which keeps your very important instructions sales from rips, tears and creases.
Underneath the instructions, service card and user guide is where the good stuff is kept, 19 packs of pure LEGO® lighting gold. All components are stored in individually sealed anti static bags which were clearly labelled to make it easy to find when referred to in the instructions.
Installation
Once you have done a couple of steps the instructions were really easy to follow, it follows suite with the typical LEGO® instructions where you have pictures instructing you what to do rather than words.
The instructions start off tackling what seemed like a mammoth task… the top of the tree!
The tiny LEDs fit very snuggly in to the leaves with a transparent stud clasping the LED in to place, this worked very well as the LED was just big enough to not slide through the hole.
I have to say that one of the biggest fears we had was that the wires would ruin the overall build of the LEGO Treehouse (21318) but they have done very well use techniques to place and hold the wires without breaking them or requiring sticky things to keep them from moving.
You can see here it slides through the pieces and nips down the end which is connected back to the trunk of the tree, I was very pleased with how they did this.
I will be honest at this point I am going to skip forward and show you the finished piece, this part of the Lightailing lighting kit was just as tedious as when the leaves were put on when we built the LEGO Treehouse but if you want an upgraded set where the whole thing lights up beautifully you have to just keep moving forward!
Once you are done all of the wires end up hanging out of the bottom of the trunk, it is a little fiddly getting it back on the lower part of the tree trunk but we found as long as the wires were all tucked neatly it was okay providing you lined it all up before hand.
Just remember at this point to keep an eye on the wires, try not to trap them anywhere as it will give you less free wire to play with when connecting it up in the later part of the kit.
Moving on to the huts seemed like a breath of fresh air!
There really wasn’t a lot to it putting the lights in the huts, there was just enough to make them light up nicely with a warm glow from the inside out.
Here are some shots of it once we had finished adding the LEDs to the other huts. You can see that they have done really well throughout making sure the wires do not spoil the actual build.
Lighting it Up!
This is the bit everyone has been waiting for isn’t it… we all know what the LEGO Treehouse (21318) looks like but if you are reading this you most likely haven’t seen it lit up like a Christmas tree!
Lightailing recommend for best performance to use the USB powered option, the power is consistent and not subject to the quality of or life left in the batteries you use (3x AA batteries).
Conclusion
I have to admit I was a bit sceptical when I opened the box and saw so many individual wires, I had seen images for these lighting kits pop up on social media and of course they always look great but the pictures are also always dark so it made me wonder if they were hiding the fact the sets ended up looking ugly. I am pleased to say that this was an unnecessary worry when it comes to Lightailing’s LEGO® Treehouse (21318) lighting kit!
If you are looking to take your LEGO® hobby to the next level I would definitely recommend taking a look at kits like this one or perhaps take a look over Lightailing’s collection as they have hundreds available.
What do you think of lighting kits? Would you get one? Do you have one already? Drop a comment below to let us know.
/* Auto generated, hash = 5dceu9kevqjdyuy2uw1atqrsu */
//TODO: Break this file down so that we can actually unit test it.
(function(window) {
/**
* Renders all unrendred LinkedIn Badges on the page
*/
window.LIRenderAll = function () {
var CALLBACK_NAME = 'LIBadgeCallback', //Must match callback on helpers.js
BADGE_NAMES = '.LI-profile-badge, .LI-entity-badge',
// TODO -- tracking param for other badge types
TRACKING_PARAM = 'profile-badge',
responsesReceived = 0, //Keeps track of number of responses recieved for proper cleanup when finished
expectedResponses = 0, //Keeps track of number of responses to expect
scripts = [ ], //Keeps track of scripts added for proper cleanup when finished
childScripts = {}, //Keeps track of child scripts to render
badges = Array.prototype.slice.call(document.querySelectorAll(BADGE_NAMES));
var i, len, badge, rendered;
for (i = 0, len = badges.length; i < len; i++) {
badge = badges[i];
rendered = badge.getAttribute('data-rendered');
if (!rendered) {
expectedResponses++;
badge.setAttribute('data-rendered', true);
renderBadge(badge);
}
}
function isCNDomain() {
if (typeof window !== "undefined") {
var hostName = window.location && window.location.hostname || '';
return (/linkedin(-ei)?.cn$/).test(hostName);
}
return false;
}
function generateUrl(isEI) {
var domainPrefix = isEI ? 'https://badges.linkedin-ei' : 'https://badges.linkedin';
if (isCNDomain()) {
return domainPrefix + ".cn/";
}
return domainPrefix + ".com/";
}
function getBadgeKeyQueryParams(badge) {
return Array.prototype.slice.call(badge.attributes).filter(function (attr) {
return attr.name.lastIndexOf('data-key-', 0) !== -1;
}).map(function (attr) {
// Most browsers automatically lowercase the attribute name when its being read
// We are calling lowercase on it again to ensure consistency for any browsers that are lagging behind.
return encodeURIComponent(attr.name.replace('data-', '').toLowerCase()) + '=' + encodeURIComponent(attr.value);
});
}
/*
* Renders a single badge on the page
* @param badge: div element of badge to render
*/
function renderBadge(badge) {
var size = badge.getAttribute('data-size'),
locale = badge.getAttribute('data-locale'),
type = badge.getAttribute('data-type'),
theme = badge.getAttribute('data-theme'),
vanity = badge.getAttribute('data-vanity'),
version = badge.getAttribute('data-version'),
isEI = badge.hasAttribute('data-ei'),
entity = badge.getAttribute('data-entity'),
isCreatePage = badge.hasAttribute('data-iscreate'),
uid = Math.round(1000000 * Math.random()),
baseUrl = generateUrl(isEI),
queryParams = [
'locale=' + encodeURIComponent(locale),
'badgetype=' + encodeURIComponent(type),
'badgetheme=' + encodeURIComponent(theme),
'uid=' + encodeURIComponent(uid),
'version=' + encodeURIComponent(version)
],
url;
if (version === 'v2') {
baseUrl += 'view';
queryParams.push('badgesize=' + encodeURIComponent(size));
queryParams.push('entity=' + encodeURIComponent(entity));
queryParams = queryParams.concat(getBadgeKeyQueryParams(badge));
} else {
baseUrl += 'profile';
queryParams.push('maxsize=' + encodeURIComponent(size));
queryParams.push('trk=' + encodeURIComponent(TRACKING_PARAM));
queryParams.push('vanityname=' + encodeURIComponent(vanity));
}
if (isCreatePage) {
queryParams.push('fromCreate=true');
}
url = baseUrl + '?' + queryParams.join('&');
badge.setAttribute('data-uid' , uid);
jsonp(url); //Calls responseHandler when done
}
/**
* Handles a response from the server. Finds badge matching badgeUid and inserts badgeHtml there
* @param badgeHtml: String representing contents of the badge
* @param badgeUid: UID of the badge to target
**/
function responseHandler(badgeHtml, badgeUid) {
responsesReceived ++;
var i, badge, uid, isCreate;
var defaultWidth = 330 // max possible width
var defaultHeight = 300 // max possible height
for (i = 0, len = badges.length; i < len; i++) {
badge = badges[i];
// isCreate needed to prevent reloading artdeco script tag
isCreate = badge.getAttribute('data-iscreate');
uid = parseInt(badge.getAttribute('data-uid'), 10);
if (uid === badgeUid) {
var badgeMarkup = `<body>${badgeHtml}</body>`
var iframe = document.createElement('iframe');
iframe.onload = function() {
var iframeBody = iframe.contentWindow.document.body;
// 5 px buffer to avoid the badge border being cut off.
iframe.setAttribute('height', (iframeBody.scrollHeight || defaultHeight) + 5);
iframe.setAttribute('width', (iframeBody.scrollWidth || defaultWidth) + 5);
};
iframe.setAttribute('frameBorder', '0');
iframe.style.display = 'block';
badge.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(badgeMarkup);
iframe.contentWindow.document.close();
replaceScriptTags(badge, isCreate);
}
}
tryClean();
}
// These functions are needed because badge markup is added via innerHtml property which does not run script tags
function replaceScriptTags(node, isCreate) {
if (shouldReplaceNode(node, isCreate)) {
node.parentNode.replaceChild(cloneScriptNode(node), node);
childScripts[node.src] = true;
} else {
var i = 0,
children = node.childNodes;
while (i < children.length) {
replaceScriptTags(children[i++], isCreate);
}
}
return node;
}
function shouldReplaceNode(node, isCreate) {
return isScriptNode(node) && !childScripts[node.src] && (!isCreate || (isCreate && !node.getAttribute('data-isartdeco')));
}
function isScriptNode(node) {
return node.tagName === 'SCRIPT';
}
function cloneScriptNode(node){
var script = document.createElement("script");
for( var i = node.attributes.length-1; i >= 0; i-- ) {
script.setAttribute( node.attributes[i].name, node.attributes[i].value );
}
return script;
}
// Gets all incoming responses
window[CALLBACK_NAME] = responseHandler;
/**
* Tries to clean added tags
**/
function tryClean() {
//Clean up after all requests are done..
//Accounts for people including script more than once
var done = (responsesReceived >= expectedResponses && expectedResponses > 0) || responsesReceived >= badges.length;
if (done) {
delete window[CALLBACK_NAME];
// remove all script tags
scripts.map(function(script){
document.body.removeChild(script);
});
}
}
/*
* Makes Jsonp request, responses handles by CALLBACK_NAME
* @param url String: url of server to make request to
*/
function jsonp(url) {
var script = document.createElement('script');
script.src = url;
scripts.push(script);
document.body.appendChild(script);
}
};
if (document.readyState === 'complete') {
window.LIRenderAll();
} else {
window.addEventListener('load', window.LIRenderAll, false);
}
})(window);