Babycam using a Unifi G3 camera

It’s been almost a year that I’ve been living in my new house and proud father of a son.

Almost every parent wants to watch their little on through a camera to see them sleeping in their bed.

There are many, many, many baby monitors on the market but in my experience they are all crap. Our house is build with a lot of concrete and none of them was able to penetrate the walls in our house and thus have a reliable video connection.

I also tried some IP/WiFi based baby monitors from for example Foscam, but these are all cheap Chinese cameras and didn’t work either. Crashing iPad apps, sending random (UDP) packets to China, half-baked UIs, etc, etc. They were all very low quality.

After a lot of frustrating I bought a Unifi Video G3 (UVC-G3-BULLET) camera and mounted it on the bed of my son.

Unifi Video G3 camera mounted on baby bed

I am using multiple Unifi video cameras around my house using Unifi Video, so for me it was just a matter of adding an additional camera to my Unifi system.

Video camera in Unifi Video

RTMP + HLS with Nginx

I also experimented with building a video stream using RTMP, ffmpeg and HLS with Nginx.

The Unifi cameras can export a RTSP stream which you can set up to live stream with Nginx. I tried this and it works for me, but with a delay of ~20s I thought it was not usable on my use-case.

It does however allow for a very easy way of building your own webcam!

Linux mdadm software RAID vs Broadcom MegaRAID 9560

In the past years I’ve said goodbye to hardware RAID controllers and mainly relied on software solutions like mdadm, LVM, Ceph and ZFS(-on-Linux) for keeping data safe.

At PCextreme we use hypervisors with local NVMe storage running in Linux’s mdadm software RAID-10. This works great! But I wasn’t satisfied with the performance for a few reasons:

  • It is expensive on the CPUs (Dual AMD Epyc 48-core)
  • It’s not super fast

We mainly use the Samsumg PM983 (1.92TB) devices and I started to look around if there is a hardware solution which could offload the RAID computation to a dedicated SoC so it wouldn’t eat up our CPU cycles.

After searching I found the Broadcom SAS3916 chip which is on the MegaRAID 9516-16i controller from Broadcom. This chipset supports NVMe devices in various RAID modes.

I wanted to benchmark Linux’s software RAID against the Broadcom controller to see if it would be faster and save us the expensive CPU cycles.

With mdadm we also looked into RAID-5/6 to have more usable space. We however found out that this eats up so many CPU cycles that it wasn’t feasible to use in production for our purposes.

Benchmarking setup

  • Ubuntu Linux 18.04 with kernel 5.3
  • SuperMicro 1114S-WN10RT
  • AMD Epyc 7302P 16-core CPU
  • 128GB Memory
  • 4x Samsung PM983 1.92TB
  • Broadcom MegaRAID 9516-i

Benchmarking will be done using fio and the main elements we are looking for:

  • QD=1, 4, 8 and 16 4k random write performance
  • CPU utilization during benchmarks

MegaRAID configuration

The RAID-10 array was created using storcli

storcli64 /c0 add vd type=raid10 drives=252:4,6,8,10 pdperarray=2

mdadadm setup

RAID-10 was set-up using this command:

mdadm --create --level=10 --raid-devices=4 /dev/md0 /dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1

fio

The fio jobs we ran to benchmark:

[global]
ioengine=libaio
direct=1
invalidate=1
bs=4k
runtime=300
filename=/var/lib/libvirt/images/fio
size=64g
rw=randwrite
numjobs=1

[rw_mdadm_1]
iodepth=1

[rw_mdadm_4]
iodepth=4

[rw_mdadm_8]
iodepth=8

[rw_mdadm_16]
iodepth=16

[rw_mdadm_32]
iodepth=32

Results

Short answer? The MegaRAID controller is much faster in RAID-10 mode and also saves up to 30% of CPU cycles on the Linux machine.

You can also download the JSON output from fio here:

In addition you can download my Open Office spreadsheet I used to generate the graphs and process the data.

Graphs

Some graphs with the results of the IOps and CPU utilization.

At QD 16~32 we seem to have found the upper limit of what the 4 NVMe devices are capable of. Going from QD 16 to 32 does not make a significant difference.
At QD32 we can still see that the MegaRAID controller uses a lot less CPU cycles then Linux’s software RAID

1Gbit fiber connection between MikroTik and Unifi switch

While replacing my router at home by a MikroTik CCR1036-8G-2S+ router I also wanted to uplink my Ubiquity switch using a Multimode (OM3) connection.

Is fiber really needed? Not really, but it saved me an additional RJ45 port on my switch which allows me to connect more.

Link up, down, up, down

The link between my MikroTik router and Unifi switch kept going up and down. In the logs on my MikroTik and Unifi switch I saw:

<14> May 26 19:19:07 SwitchPatchkast DOT1S[dot1s_task]: dot1s_sm.c(314) 454679 %% Port (26) inst(0) role changing from ROLE_DESIGNATED to ROLE_DISABLED
<14> May 26 19:19:07 SwitchPatchkast DOT1S[dot1s_task]: dot1s_sm.c(314) 454677 %% Port (26) inst(0) role changing from ROLE_DISABLED to ROLE_DESIGNATED
<13> May 26 19:19:07 SwitchPatchkast TRAPMGR[trapTask]: traputil.c(743) 454676 %% Link Up: 0/26
<14> May 26 19:18:58 SwitchPatchkast DOT1S[dot1s_task]: dot1s_sm.c(314) 454668 %% Port (26) inst(0) role changing from ROLE_DESIGNATED to ROLE_DISABLED
<13> May 26 19:18:58 SwitchPatchkast TRAPMGR[trapTask]: traputil.c(743) 454667 %% Link Down: 0/26
19:25:12 interface,info sfp-sfpplus1 link up (speed 1G, full duplex)
19:25:20 interface,info sfp-sfpplus1 link down
19:25:21 interface,info sfp-sfpplus1 link up (speed 1G, full duplex)
19:25:29 interface,info sfp-sfpplus1 link down
19:25:30 interface,info sfp-sfpplus1 link up (speed 1G, full duplex)
19:28:48 interface,info sfp-sfpplus1 link down

I am using optics from FlexOptix which I programmed to MikroTik and Ubiquity using their programmer. (We have those at work).

Auto negotiation

After trying many things it turned out that turning off Auto Negotation on both the switch and the router resolved the issue.

On the switch I turned it off via the UI of the Unifi Controller and forced it to 1000 FDX.

On the router I turned it off using the MikroTik CLI:

[admin@router] > /interface ethernet export
/interface ethernet
set [ find default-name=sfp-sfpplus1 ] advertise=1000M-full auto-negotiation=no speed=1Gbps
set [ find default-name=sfp-sfpplus2 ] advertise=1000M-full speed=1Gbps
[admin@router] >

sfp-sfpplus1 is the interface I am using for the connection to my Unifi switch.

Link is now online! Below is a picture of my 19″ rack at home.

Exploring the CAN bus of my Tesla Model S

The CAN bus of a Tesla vehicle can show some interesting information about the state of different components in the vehicle.

Using a CAN bus cable, Bluetooth adapter and a App on your mobile phone you can gain much more insight on your Tesla vehicle.

I own two Tesla vehicles:

  • S85 from September 2013 (pre face-lift)
  • S100D from September 2018

Somewhere around 2015 Tesla switched to a different connector for the CAN bus so I needed two different cables. I bought my cables in Germany at EMDS.

EMDS also sells a cable for Model 3. I haven’t used this one as I don’t own a Model 3.

The CAN bus connector in a Model S can be found under the MCU’s main screen in the vehicle. You need to pull down the ‘chubby’ and there you will find the connector:

Cable connected to my Model S85

I am using the TM-Spy app on iOS for reading the values on my iPhone.

Screenshot of TM-Spy on iOS

For Android there is Scan My Tesla which also seems to be a very good app. I don’t have an Android device, so I was not able to test it.

I was mainly looking for these values:

  • Usable Full
  • DC Charge Total
  • AC Charge Total

After 253.543km of driving my battery has 75.6kWh of remaining capacity where this was ~81kWh when it was new. (The 85kWh battery was actually a 81kWh battery….)

Tesla also throttles a vehicle’s SuperCharging capabilities after more than X amount (I don’t know the exact value) of DC charging. My car seems to be affected as I SuperCharged a lot.

Charge Total is not a total sum of AC+DC, but from what I’ve read early firmwares did not count AC and DC charging in different values.

Interesting information though! I encourage everybody to use this information to gather more information about their vehicle’s state.

Happy exploring!

Replacing the eMMC in my Tesla Model S

Tesla’s vehicles are awesome. I own a S85 from 2013 and a S100D from 2018. I’ve driven 260.000km and 70.000km with these two vehicles and I love it.

There is however a design flaw in the early Tesla models which can become a very expensive reparation if not performed in time.

Version of of the MCU (Media Control Unit) which was installed up until early 2018 in Tesla S/X runs and is a ticking time bomb.

The problem is the Flash Memory (eMMC) which holds the Operating System of the computer. This wears out over time due to writing data to it.

Writing happens when you use the car. It caches Spotify, Google Maps and many more things. Even when the car is parked the MCU stays running and writes to the eMMC chip.

Eventually this chip will wear out. Before it does it becomes very slow and this results in the MCU becoming super sluggish, unresponsive, the screen reboots at random moments, bluetooth issues, etc, etc.

Inside of the Tesla MCU1
The eMMC chip

A lot has been written about this, so I won’t write to much. Short: Tesla will charge you around 2000 EUR/USD for a new MCU.

I choose to replace this eMMC chip myself and this was a lot cheaper! Total cost was <500 EUR.

Around the world there are a couple of companies doing these replacements. I replaced my eMMC chip together with Loek from Laadkabelwinke.nl (Netherlands): https://www.laadkabelwinkel.nl/tesla-mcu1-emmc-vervangen-reparatie

On Tesla Motors Club there are various topics about these replacements, one for example: https://teslamotorsclub.com/tmc/threads/preventive-emmc-replacement-on-mcu1.152489/

I highly recommend everybody with a Model S/X to replace this eMMC chip before it fails.

The chip will wear out and this causes all kinds of problems. I can’t stress this enough. Replace the chip before it’s too late!

In Europe I would recommend to go to Laadkabelwinkel.nl and have them replace the chip.

Enjoy your Tesla!

HAProxy in front of Ceph Manager dashboard

The Ceph Mgr dashboard plugin allows for an easy dashboard which can show you how your Ceph cluster is performing.

In certain situations you can’t contact the Mgr daemons directly and you have to place a Proxy server between your computer and the Mgr daemons.

This can be done easily with HAProxy and the following configuration which assumes that:

  • SSL has been disabled in the Dashboard plugin
  • Dashboard plugin listens in port 8080
  • Mgr is running on the hosts mon01, mon02 and mon03
global
  log         127.0.0.1 local1
  log         127.0.0.1 local2 notice

  chroot      /var/lib/haproxy
  pidfile     /var/run/haproxy.pid
  maxconn     4000
  user        haproxy
  group       haproxy
  daemon

  stats socket /var/lib/haproxy/stats

defaults
  log                     global
  mode                    http
  retries                 3
  timeout http-request    10s
  timeout queue           1m
  timeout connect         10s
  timeout client          1m
  timeout server          1m
  timeout http-keep-alive 10s
  timeout check           10s
  maxconn                 3000
  option                  httplog
  no option               httpclose
  no option               http-server-close
  no option               forceclose

  stats enable
  stats hide-version
  stats refresh 30s
  stats show-node
  stats uri /haproxy?stats
  stats auth admin:haproxy

frontend https
  bind *:80
  default_backend ceph-dashboard

backend ceph-dashboard
  balance roundrobin
  option httpchk GET /
  http-check expect status 200
  server mon01 mon01:8080 check
  server mon02 mon02:8080 check
  server mon03 mon03:8080 check

You can now point your browser to the URL/IP of your HAProxy and use your Ceph dashboard.

In case a Mgr machine fails the health checks of HAProxy will make sure it fails over to on of the other Mgr daemons.

VXLAN with VyOS and Ubuntu 18.04

VXLAN

Virtual Extensible LAN uses encapsulation technique to encapsulate OSI layer 2 Ethernet frames within layer 4 UDP datagrams. More on this can be found on the link provided.

For a Ceph and CloudStack environment I needed to set up a Proof-of-Concept using VXLAN and some refurbished hardware. The main purpose of this PoC is to verify that VXLAN works with CloudStack, Ceph and Ubuntu 18.04

VyOS

VyOS is an open source network operating system based on Debian Linux. It supports VXLAN, so using this we were able to test VXLAN in this setup.

In production a other VXLAN capable router would be used, but for a PoC VyOS works just fine running on a regular server.

Configuration

The VyOS router is connected to ‘the internet’ with one NIC and the other NIC is connected to a switch.

Using static routes a IPv4 subnet (/24) and a IPv6 subnet (/48) are routed towards the VyOS router. These are then splitted and send to multiple VLANs.

As it took me a while to configure VXLAN under VyOS

I’m only posting that configuration.

interfaces {
    ethernet eth0 {
        address 31.25.96.130/30
        address 2a00:f10:100:1d::2/64
        duplex auto
        hw-id 00:25:90:80:ed:fe
        smp-affinity auto
        speed auto
    }
    ethernet eth5 {
        duplex auto
        hw-id a0:36:9f:0d:ab:be
        mtu 9000
        smp-affinity auto
        speed auto
        vif 300 {
            address 192.168.0.1/24
            description VXLAN
            mtu 9000
        }
    vxlan vxlan1000 {
        address 10.0.0.1/23
        address 2a00:f10:114:1000::1/64
        group 239.0.3.232
        ip {
            enable-arp-accept
            enable-arp-announce
        }
        ipv6 {
            dup-addr-detect-transmits 1
            router-advert {
                cur-hop-limit 64
                link-mtu 1500
                managed-flag false
                max-interval 600
                name-server 2a00:f10:ff04:153::53
                name-server 2a00:f10:ff04:253::53
                other-config-flag false
                prefix 2a00:f10:114:1000::/64 {
                    autonomous-flag true
                    on-link-flag true
                    valid-lifetime 2592000
                }
                reachable-time 0
                retrans-timer 0
                send-advert true
            }
        }
        link eth5.300
        mtu 1500
        vni 1000
    }
    vxlan vxlan2000 {
        address 109.72.91.1/26
        address 2a00:f10:114:2000::1/64
        group 239.0.7.208
        ipv6 {
            dup-addr-detect-transmits 1
            router-advert {
                cur-hop-limit 64
                link-mtu 1500
                managed-flag false
                max-interval 600
                name-server 2a00:f10:ff04:153::53
                name-server 2a00:f10:ff04:253::53
                other-config-flag false
                prefix 2a00:f10:114:2000::/64 {
                    autonomous-flag true
                    on-link-flag true
                    valid-lifetime 2592000
                }
                reachable-time 0
                retrans-timer 0
                send-advert true
            }
        }
        link eth5.300
        mtu 1500
        vni 2000
    }
}

VLAN 300 on eth5 is used to route VNI 1000 and 2000 in their own multicast groups.

The MTU of eth5 is set to 9000 so that the encapsulated traffic of VXLAN can still be 1500 bytes.

Ubuntu 18.04

To test if VXLAN was actually working on the Ubuntu 18.04 host I made a very simple script:

ip link add vxlan1000 type vxlan id 1000 dstport 4789 group 239.0.3.232 dev vlan300 ttl 5
ip link set up dev vxlan1000
ip addr add 10.0.0.11/23 dev vxlan1000
ip addr add 2a00:f10:114:1000::101/64 dev vxlan1000

That works! I can ping 10.0.0.11 and 2a00:f10:114:1000::1 from my Ubuntu 18.04 machine!

Building a Lithium battery for my electric scooter

Disclaimer

I am not a battery expert nor am I claiming to be one! I got all my information from the internet and I think designed and build my battery correctly.

Always use common sense and do not blindly trust the information I (or anybody else) am/is putting on the internet.

Novox C20

In 2010 I bought a Novox C20 25km/h electric scooter. Novox was (they are gone) Dutch manufacturer of electric scooters. It seems that they (partially) bought the scooters in China and rebranded them to their brand Novox. It seems that many parts of it were actually from the Chinese manufacturer Tysong.

I previously wrote a dutch post and a english post about this scooter.

The model I have is the 25km/h version equipped with a 2.5kW electric motor with 4 12V 40Ah batteries.

Realistically this scooter had a range of about 35 ~ 40km before running out of juice.

25km/h

In the Netherlands we have two types of scooters. We call them snorfiets (25km/h, blue license plate) or bromfiets (45km/h, yellow plate). My scooter is a snorfiets which means I do not have to wear a helmet.

The primary purpose for the scooter is going to the beach in summer, use it when it’s nice weather and when I want to go somewhere which is a bit to far to go by bicycle.

4x 12V 40Ah

Originally the scooter had 4 12V 40Ah batteries which (in theory) is roughly 1.9kWh of capacity. These were lead acid batteries and each weight 12kg, so the total weight of the batteries was nearly 50kg.

Over the years the range and performance declined until the batteries died completely. After reading about DIY batteries using 18650 Lithium batteries I decided to build my own!

Designing the battery

After I decided to design and build my own battery I went out to gather information. I watched endless hours of videos on YouTube and I also bought a book:

With the information from YouTube, that book and other sources I designed a 14S15P battery.

14S15P

A 14S15P configuration means 14 Cells in Series and 15 Cells Parallel. The total amount of cells would be: 210 (14*15).

The nominal voltage of the battery would be 50.4V (3.6*14) and the maximum voltage 58.8V (4.2*14).

The existing controller in the scooter would not be able to handle that voltage so I would have to swap the controller. That’s something I’ll explain in a upcoming post.

On AliExpress I searched for 18650 battery cell holders for a 14S5P pack and ordered three sets. Combining them would give me a 14S15P battery pack which would physically fit in my scooter.

Samsung INR18650-35E

During my search for the correct cell I selected the Samsung INR18650-35E cell. This cell has a capacity of 3.500mAh and 210 of them would sum up to a total capacity of 2646Wh (3.6 * 3500 * 210 / 1000) or 2.6kWh for my scooter.

Each cell can deliver 10A of current so 15 of them in parallel would be able to provide 150A of current. With a nominal voltage of 50V that would be 7500W or 7.5kW.

As the motor in my scooter is rated for 2.5kW I would only need 50A of current. 50A or 2.5kW was my design target. Anything above it would be a bonus.

After searching I found the Dutch shop Nkon which has a good reputation and was able to deliver the INR18650-35E for a good price. So I ordered 220 cells (10 spare).

Next to the cells I ordered 15m of 0.15mm Nickel strip to use when spotwelding all the cells together.

Battery Management System

The next important thing was a Battery Management System (BMS). A BMS makes sure the cells stay in a healthy state by doing various things:

  • Protecting them against under -or overvoltage
  • Protecting against a high charge or discharge current
  • Making sure the cells are balanced

There are good and bad BMS out there. At first I thought I’d buy one on AliExpress but after reading on the dutch forum of Tweakers in the topic about electric scooters I purchased a TinyBMS s516 from Energus Power Solutions. It’s not the cheapest, but it does do its job: Protecting my 210 cells!

In addition to the BMS I ordered:

  • USB programming cable
  • Temperature sensors
  • Bluetooth module
  • Balancing Wires

Spotwelding

To connect all the cells together you need to use spotwelding as soldering would damage the cells badly due to the heat.

At first I bought a Sunko 709A spotwelder on AliExpress. Short story: A waste of money!

After searching a bit more I found a Arduino based spotwelder made by Malectrics in Germany.

This spotwelder works great with a Bosch 12V 44A 440A car battery. I made a short video and put it on YouTube.

In addition a picture of the spotwelder connected to the battery.

I never used a spotwelder before nor did I build a battery. I started with building a small 3S5P 12V battery to test my welding skills.

Safety First! Remember to wear gloves and eye protection when working with a spotwelder and/or batteries. Also make sure there are no loose tools or wires on your workplace and again, use common sense!

I am now using this battery as a DIY powerbank with a 12V and USB output.

Building it

After I got some practice on building the small battery I just started working on the big battery. Cutting nickel to length and I started to build the blocks.

This took a lot of time, probably over 40 hours as I slowly build my first big battery and still needed to learn.

I ended up stacking two strips of 0.15mm nickel on top of each other to handle my 50A target current.

You can also see the balancing wires of the BMS go to the positive terminal of each series. The manual of the BMS has clear instructions on how to wire them.

From the Nickel I went to 8AWG wire which I connected to a SB50 connector. Using that connector I would connect the battery Plus and Minus to the BMS and the BMS to the controller. The SB50 connector is rated for 50A and thus meets my requirements. I got the connectors from a local supplier.

Using a tape, lexan and some screw the end result (without BMS) looked like this:

And with my TinyBMS connected to it:

The tiny red wires are the balancing wires used by the BMS to monitor the cells in series and balance charge them when needed.

BMS settings

Using a Windows tool you can monitor and configure the BMS using a USB cable (which you have to buy).

There are various settings you can change, but the main values I set were:

  • Low voltage cut-off: 3.25V
  • High voltage cut-off: 4.15V
  • Maximum discharge currect: 75A

Although the cells can range from 3.2V to 4.2V I decided to take a 0.05V safety margin to increase the lifetime of the cells. I might lower the maximum voltage per cell to 4.1V in the future, but that’s something I still have to decide.

Using the BMS tool you can see the voltage of each individual series of cells and see them change while charging the battery.

Charging and Charger

To charge this battery I also needed a new charger as the old charger was not suited for Lithium and the voltage was too low.

I bought a 58.8V/5A charger on AliExpress which I’m using for now. It does seem to do the job just fine for now. The BMS isn’t complaining (yet).

Using XT90 connectors I connect my charger to the BMS although the scooter has a XLR input. But internally I’m connecting all those wires using XT90 connectors.

I got my XT90 connectors at Hobbyking as they also have a local warehouse in the Netherlands and have a good reputation.

Weight

The four old batteries had a combined weight of nearly 50kg where the new battery weighs slightly less than 12kg with everything connected.

That’s a weight reduction of 38kg! That will benefit acceleration, handling and range positively.

End result

The end result is a 2,6kWh battery consisting out of 210 cells connected in a 14S15P configuration with a nominal/maximum voltag of 50.4V/58.8V.

My initial calculations and tests tell me that when driving ~30km/h (Yes, I did some tuning!) the motor draws about 20A. That’s about 1000W at 50V.

Since the battery is 2600Wh I should be able to drive for roughly 2 hours and 30 minutes at 30km/h before the battery is empty.

30km for 2.5 hours would mean a range of 75km which is more then enough for my driving habits with this scooter.

With the original batteries I had a range of roughly 40km, but I never tried if it actually got that far. I think I improved the range with nearly 75% with this new battery.

In this picture you see the battery installed in the scooter and hooked up to the controller. A post about the controller and connecting it all will follow later.

Costs

The total costs for the cells, BMS, wire and connectors is about EUR 940,00 which can be broken down into:

  • Cells: EUR 650,00
  • BMS: EUR 200,00
  • Wires: EUR 40,00
  • Connectors: EUR 50,00
  • Time: 50 hours!

For me it was a cool project and something I could learn a lot from.

BIG Thanks

There are a few people and sources I have to thank big-time for their information on the internet.

  • jehugarcia on YouTube
  • User flippy.nl on Tweakers.net
  • All the other people sharing information!

I wouldn’t have been able to do this without those people. Thanks!

Performance

The battery is currently installed in the scooter and I’m still in the process of fine-tuning the controller.

My initial test drives tell me that the performance improved a lot! Acceleration to 30km/h is a lot quicker and I feel the motor has a lot more torque than it had before. This is mainly due to the battery being able to provide the current required to power the motor. The weight reduction can also be felt clearly and also contributes to the improved acceleration.

One of the cool things is that the scooter now has regenerative breaking thanks to the new controller.

A post regarding the controller and connecting it all will follow. Stay tuned!

Getting connection URL from (Flask) SQLAlchemy

While working with Flask‘s SQLAlchemy extension I ran into the case where I wanted to obtain the host I was connected to combined with the username and password.

As I didn’t want to parse the URL I provided earlier to SQLAlchemy (and I didn’t have it available at that part of the code) I looked for a method to obtain it from SQLAlchemy.

It turns out this is not (or poorly) documented, but the Engine object has a attribute called url.

>>> db.engine.url
mysql+mysqlconnector://sqlmanager:***@localhost/sqlmanager?charset=utf8
>>>

This is actually a sqlalchemy.engine.url.URL object which contains attributes with the connection information:

>>> url = db.engine.url
>>> url.host
'localhost'
>>> url.username
'sqlmanager'
>>> url.password
'supersecretpassword'
>>> url.database
'sqlmanager'
>>> 

This was the information I needed and allowed me to use this information elsewhere.

Calculating SLAAC IPv6 Address in Java

SLAAC

With IPv6 a host on a network can use StateLess Address AutoConfiguration (SLAAC) to configure it’s network.

Routers will send out Router Advertisements telling the network which subnet is used in the network.

Based on their MAC address (modified EUI-64) a host will then obtain a IPv6 it will use.

Java

For the Apache CloudStack project I had to write Java code which would take a subnet and a MAC address as an argument and would generate a IPv6 SLAAC address from it.

Combining subnet 2001:db8:100::/64 with MAC address 06:7a:88:00:00:8b yields IPv6 address 2001:db8:100:0:47a:88ff:fe00:8b.

/*
 * Java code using Java-ipv6 from Google Code to convert
 * a given IPv6 subnet and a MAC address into a IPv6 address
 * calculated using SLAAC.
 *
 * Author: Wido den Hollander 
*/
import com.googlecode.ipv6.IPv6Address;
import com.googlecode.ipv6.IPv6Network;

public class IPv6EUI64 {
    public static IPv6Address EUI64Address(final IPv6Network cidr, final String macAddress) {
        if (cidr.getNetmask().asPrefixLength() > 64) {
            throw new IllegalArgumentException("IPv6 subnet " + cidr.toString() + " is not 64 bits or larger in size");
        }

        String mac[] = macAddress.toLowerCase().split(":");

        return IPv6Address.fromString(cidr.getFirst().toString() +
                Integer.toHexString(Integer.parseInt(mac[0], 16) ^ 2) +
                mac[1] + ":" + mac[2] + "ff:fe" + mac[3] +":" + mac[4] + mac[5]);
    }

    public static void main(String[] argv) {
        IPv6Network cidr = IPv6Network.fromString("2001:db8:100::/64");
        String mac = "06:7a:88:00:00:8b";
        IPv6Address eui64addr = EUI64Address(cidr, mac);

        /* This will print 2001:db8:100:0:47a:88ff:fe00:8b */
        System.out.println(eui64addr);
    }
}

The code can also be found on my Github Gist page.