Func%onal Programming at LumiGuide
Bas van Dijk? Sensor Sense (Nijmegen) Be?er (Zürich, Switzerland) ZuriHac! CTO @ LumiGuide (Nijmegen)
I some%mes wear a suit ;)
LumiGuide
P-route Bicycle
Rack-independent sensors
1 sensor is able to simultaneously detect 40-60 cycle rack spaces a minute
Detec%on of rack-free parking spaces
Detec%on of rack-free parking spaces
Outdoor signage Signage Indoor signage
Management SoZware
GHCJS & blaze-react (Simon Meier)
GHCJS & blaze-react (Simon Meier) data App state action = App { appinitialstate :: state, appinitialrequests :: [IO action], appapplyaction :: action -> Transition state action, apprender :: state -> Html action } type Transition state action = state -> (state, [IO action]) runapp :: App state action -> IO () data Html action = p :: Html action -> Html action input :: Html action (!) :: ( Attributable h action) => h -> Attribute action -> h onvaluechange :: (Text -> action) -> Attribute action
thea: Haskell binding to OpenCV-3.1 exposed-modules: OpenCV, OpenCV.Core, OpenCV.Core.Types, OpenCV.Core.Types.Mat, OpenCV.Core.Types.Mat.HMat, OpenCV.Core.Types.Mat.Repa, OpenCV.Core.ArrayOps, OpenCV.Unsafe, OpenCV.ImgProc.ImgFiltering, OpenCV.ImgProc.GeometricImgTransform, OpenCV.ImgProc.MiscImgTransform, OpenCV.ImgProc.Drawing, OpenCV.ImgProc.StructuralAnalysis, OpenCV.ImgProc.ObjectDetection, OpenCV.ImgProc.Types, OpenCV.ImgCodecs, OpenCV.HighGui, OpenCV.Video, OpenCV.JSON
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format data OutputFormat = OutputBmp OutputExr OutputHdr Bool OutputJpeg JpegParams OutputJpeg2000 OutputPng PngParams OutputPxm Bool OutputSunras OutputTiff OutputWebP Int freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> inline-c (Francesco Mazzoli, Mathieu Boespflug FP Complete) alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format cvexcept :: QuasiQuoter cvexcept = C.block { quoteexp = \s -> quoteexp C.block (cvexceptwrap s) } cvexceptwrap :: String -> String cvexceptwrap s = "Exception * {\n\ \ try\n\ \ {\n " <> s <> "\n\ \ return NULL;\n\ \ }\n\ \ catch (const cv::exception & e)\n\ \ {\n\ \ return new cv::exception(e);\n\ \ }\n\ \}" freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
imencode :: OutputFormat -> Mat -> Either CvException ByteString imencode format mat = unsafeperformio $ withmatptr mat $ \matptr -> withcstring ext $ \extptr -> alloca $ \(bufptrptr :: Ptr (Ptr CUChar)) -> alloca $ \(vecptrptr :: Ptr (Ptr ())) -> alloca $ \(c'bufsizeptr :: Ptr CInt) -> mask_ $ do ptrexception <- [cvexcept const int * const paramsptr = $vec-ptr:(int * params); std::vector<uchar> * vec = new std::vector<uchar>(); *$(void * * vecptrptr) = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + $vec-len:params); cv::imencode( $(char * extptr), *$(Mat * matptr), *vec, params ); *$(int * c'bufsizeptr) = vec->size(); *$(unsigned char * * bufptrptr) = &((*vec)[0]); ] vecptr <- peek vecptrptr if ptrexception /= nullptr then do freevec vecptr Left <$> cvexceptionfromptr (pure ptrexception) else do bufsize <- peek c'bufsizeptr bufptr <- peek bufptrptr bs <- BU.unsafePackCStringFinalizer (castptr bufptr) (fromintegral bufsize) (freevec vecptr) pure $ Right bs where (ext :: String, params :: Vector CInt) = marshalloutputformat format freevec :: Ptr () -> IO () freevec vecptr = [C.exp void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecptr)) } ]
extern "C" { Exception * inline_c_opencv_imgcodecs_2_25828b73bb33f9d4698167b33554fcb1f7f72415 ( int * params_inline_c_0, void ** vecptrptr_inline_c_1, long params_inline_c_2, char * extptr_inline_c_3, Mat * matptr_inline_c_4, int * cbufsizeptr_27_inline_c_5, unsigned char ** bufptrptr_inline_c_6 ) { try { const int * const paramsptr = params_inline_c_0; std::vector<uchar> * vec = new std::vector<uchar>(); *vecptrptr_inline_c_1 = reinterpret_cast<void *>(vec); std::vector<int> params(paramsptr, paramsptr + params_inline_c_2); cv::imencode( extptr_inline_c_3, *matptr_inline_c_4, *vec, params ); *cbufsizeptr_27_inline_c_5 = vec->size(); *bufptrptr_inline_c_6 = &((*vec)[0]); return NULL; } catch (const cv::exception & e) { return new cv::exception(e); } }
Nix Nix: a purely, func%onal, lazy and dynamically typed programming language nixpkgs: a git repository of Nix expressions for Linux & Mac OS X packages NixOS: Nix-based Linux distribu%on Hydra: Nix-based con%nuous build system nixops: deploy sets of NixOS machines
$ ls /nix/store 0006h2k02xc3hjy7ddr0xk3b4mxzv2vx-gsl-1.16.tar.gz.drv 006cjanl30r789cis6qww6hh3ja2ri2w-engineers.nix 008gllqbf452a044bwnwgylaf7a9dlyf-perl-Text-Glob-0.09 008s4z7vx9zs78bk6zjfc2jw30mlj6vg-python2.7-setuptools-18.2 009fqvhziw9zj7b3a4qi624y93sklk4b-namespace-clean-0.25.tar.gz.drv 00b8q75g8lw8flvsnmcsjanxpc1afl80-nodejs-isarray-0.0.1.drv 00bnnx5ypgkk5g38wk37y9s1vjbgmagr-python-memcached-1.51.tar.gz.drv 00g8fmql256da1d2ks587d33k1qlndnk-String-ToIdentifier-EN-0.11.tar.gz 00gm250lj5wwqlq7q8gyfskcgccvmp79-topgit-0.9.tar.gz.drv
LumiOS NixOS extended with our own modules Configures everything: All facility servers All central servers All support servers All the worksta%ons of our engineers (virtualbox, hyperv and real hardware)
Development $ nix-build A lumi.facility.client /nix/store/z2mfz8h4dpcbrlmknpkqfmrjg9ni48l7-lumi-facility-client-0.0.1 $ nix-shell A lumi.facility.client
Hydra Con%nuous build system let pkgs = import./default.nix; workstation = hardware : (import (import <lumi/nixpkgs.nix> + /nixos) { configuration = import <lumi/os/workstation/hydra> hardware; }).system; in { central = pkgs.lumi.central; facility.client = pkgs.lumi.facility.client; facility.server = pkgs.lumi.facility.localserver; facility.install-cd-hydra = pkgs.lumi.facility.install-cd-hydra; pris-gateway = pkgs.lumi.pris-gateway; sensors-logger = pkgs.lumi.sensors-logger; py-vision-playground = pkgs.lumi.py-vision-playground; hs-vision-playground = pkgs.lumi.hs-vision-playground; command-poller = pkgs.lumi.command-poller; tender-slurper = pkgs.lumi.tender-slurper; thea thea-profiled = pkgs.haskellpackages.thea; = pkgs.profiledhaskellpackages.thea; workstation.virtualbox workstation.hyperv workstation.real = workstation <lumi/os/workstation/hardware/virtualbox.nix>; = workstation <lumi/os/workstation/hardware/hyperv.nix>; = workstation <lumi/os/workstation/hardware/real.nix>; }
nixops: deploying NixOS machines nixops create \ -state state.nixops \ --deployment stalling-net \ <stalling-net.nix>' \ <stalling-net-hardware.nix>'
stalling-net.nix let facility = namespace: in { network.description = "Stalling network"; zeus = import <lumi/os/central>; hera = { imports = [ <lumi/os/support> ]; support.pgmaster = "zeus"; }; nijmegen-verloren-toren = facility 1; utrecht-lange-koestraat = facility 2; utrecht-zadelstraat = facility 3; utrecht-vredenburg = facility 4; utrecht-westplein = facility 5; utrecht-stadhuis = facility 10; Logical configura%on utrecht-jaarbeursplein = { config,... }: { imports = [ <lumi/os/pris-gateway> ]; services.lumi.pris-gateway-poster.facilityservice = facilityservice config.networking.hostname; }; denhaag-stadhuis = facility 13; amsterdam-sportpark-ijburg = facility 14; }
stalling-net-hardware.nix let hetzner = mainip: ; facility = nic: ipaddress: defaultgateway: ; in { zeus = {imports = [ (hetzner 123.321.123.321") <lumi/os/central/hardware.nix> ];}; hera = {imports = [ (hetzner 321.123.321.123") <lumi/os/support/hardware.nix> ];}; } # nic ipaddress defaultgateway nijmegen-verloren-toren = facility "eno1" "10.0.1.2" "10.0.1.1"; utrecht-lange-koestraat = facility "eno1" "10.0.2.2" "10.0.2.1"; utrecht-zadelstraat = facility "eno1" "10.0.3.2" "10.0.3.1"; utrecht-vredenburg = facility "eno1" "10.0.4.2" "10.0.4.1"; utrecht-westplein = {imports=[(facility "eno1" "10.0.5.2" "10.0.5.1") (router-rebooter "10.0.5.1")];}; utrecht-jaarbeursplein = facility "enp3s0" "10.0.6.2" "10.0.6.1"; utrecht-stadhuis = facility "eno1" "10.0.7.2" "10.0.7.1"; amsterdam-sportpark-ijburg = facility "enp0s25" "10.0.8.2" "10.0.8.1"; denhaag-stadhuis = facility "enp3s0" "10.0.9.2" "10.0.9.1"; Physical configura%on
Deploy the network configura%on nixops deploy \ -state state.nixops \ --deployment stalling-net Provisions machines and other resources Copies Nix closures Ac%vates new configura%on
Have fun parking your bike!
Please ask me something?