IoT - Halloween V2

Akka  Finite State Machine  Arduino  Grails  Automated Light Show  IOT  Groovy  Home Genie  MQTT  Singing Pumpkins  Christmas  Halloween 
Oct 11, 2016

Github project link: https://github.com/yakoob/halloween

The Goal

When children approach the house the Pumpkin Patch comes to life providing an interactive environment based on motion and sound detection.

Service Layer

The following technologies were used:

ActorSystem:

Using Akka with a Finite State Machine DSL that various actors can implement to transition their internal state.

These actors facilitate the state of the IoT devices involved.

  • Android Projectors
  • Arduino
  • Philips Hue
  • GE smart power switch
  • Aeontech multi-sensor
  • FSM code | FSM grammar code | preview actor code

    Using the DSL is very easy.

    1) Implement the FSM trait which provide the actor with an instance of a Finite State Machine.

    class Projector extends BaseActor implements FSM {}
    

    2) Configure the FSM DSL durring the initialization of your actor.

        @Override
        void configureFsmDsl() {
    	    fsm.record().onCommands([Play]).fromState(Any).goToState(Playing).transition = { Command command ->
    	        remoteDispatch(command)
    	    }
    
    	    fsm.record().onCommands([Off, Pause]).fromState(Any).goToState(Paused).transition = { Command command ->
    	        remoteDispatch(command)
    	    }
    
    	    fsm.record().onCommands([Resume]).fromState(Paused).goToState(Playing).transition = { Command command ->
    
    	        if (!currentVideo || currentVideo == Video.Name.NONE)
    	            return new Guard(reason: "ineligible video for command:Resume")
    
    	        remoteDispatch(command)
    
    	    }
        }
    

    3) Fire relevent messages to your Finite State Machine in your actors onRecieve method.

    	@Override
        void onReceive(Object message) throws Exception {      
            if (message instanceof Command)
                fsm.fire(message)            
        }
    

    Android:

    Enables playing and stopping of videos as well as device commands using subtitles "timedText" to have fine grain control of IoT devices... i.e: blow smoke at 1:01:02.
    android singing pumpkins code | actor code
    android hologram code | actor code


    Arduino:

    Sound Detection. arduino code | actor code
    Smoke Machine. arduino code | actor code


    Philips Hue Bloom(s) with Bridge:

    Enables control of Hue lights [color/luminance] via a rest API. preview code


    Materials / Application:

    Easy Popup with two 7x11 tarpes.

    This provides a great platform for arranging your Pumpkin Patch. Attach the tarps to the side and back of the popup so that luminance levels can be controlled. You will also find the aluminum supporting structures useful for cable management and hanging props.

    Polyurethane pumpkins from Michaels

    Cover one side of the pumpkin with blue painters tape and draw your spooky face. The tape serves two purposes:

    1. 1) provides a platform for drawing your design one or more times.
    2. 2) exposes freshly cut areas for spray painting black; while protecting untouched orange areas.
    I used an X-Acto knife to cut out my design. - “this can be dangerous, so proceed with caution at your own risk...”
    Install low heat lighting. - “high heat lighting will cause a fire”. I used 3W flicker flame LED’s. It is important to get them all connected to the same power cords so you can programmatically control their ON and OFF states as they will ultimately be connected to a IOT power switch and behave accordingly to our Halloween ActorSystem.

    Decorative hay bales from Michaels.

    Stagger different sized hays bales for which to arrange pumpkins on.

    Decorative Ivy from Michaels

    Weave in and out of hay bales

    Spider web looking cloth from Michaels

    Hang the webs from the ceiling and sides of the Easy Popup

    Three centerpiece pumpkins for projecting singing pumpkins upon

    Projectors

    Two Android based projectors that can be programed as desired. I have 1 projector for the singing / joke telling pumpkins and another for the backdrop hologram

    Something to hide your projector in

    I built a box from supplies I picked up at Lowes. I left space in between side panels so the equipment inside doesn’t overheat.

    Audio Detection

    The ability to detect current audio levels is valuable in creating an interactive experience. Not only does this allow for the lights to have a Color / Luminance Schema that matches your music, they will also react to sounds of trick or treaters. I’ve added a bonus that blows smoke and powers the strobe light when the sum of the last 5 received audio values exceeds a certain level.

    Smoke machine with a toggle switch for disbursement of smoke

    Like the projector; the smoke machine requires physical interaction to have smoke blow on demand. The smoke machine must be powered on for about 5 minutes so that it can heat up enough to blow smoke when a switch is toggled. I decided to alway supply power so that it is in a constant ready state and mount a servo to the blow smoke switch. Now when the Halloween Actor System is in a automation on state smoke will blow every 30 seconds for 2 seconds

    Load a program on your arduino to take commands via rest and translate them into commands to the servo

    Christmas IOT

    Android  Arduino  Finite State Machine  Grails  Automated Light Show  IOT  Actor Model  Groovy  MQTT 
    Jan 9, 2016

    The following technologies were used:

    ActorSystem:

    Controls the Android tablet as well as the Arduiono-Relay Module for automation of lighting/music using Grails, Akka, MQTT, Async-REST.
    preview code

    LightController:

    Arduino application controlling a relay module by exposing an API for various lighting methods via REST.
    preview code

    MediaController:

    Enables playing and stopping of songs via MQTT using android sdk.
    preview code

    Clone from Github:

    https://github.com/yakoob/christmas

    Ahmad Family - 2014

    Dec 26, 2014

    It's alive!!! ahhh... no, it's UnDead!!!

    Oct 14, 2014

    Tell your Undead Stories!!!

    clone it from github

    Finite State Machine DSL

    Akka  Finite State Machine 
    Sep 8, 2014

    A continuation of my previous post... This introduction to a Finite State Machine DSL will show you how I am able to better manage event based transitional logic.

    Lets focus on the InboundChannelActor "incoming call".

    First we need to add an instance of a State Machine so that we can configure it when each inbound channel is initialized. I include a trait that allows me to have a new instance of a FiniteStateMachine, then I define the DSL which is added to the State Machine's transitions registry.

    trait ChannelState implements Channel {
        public FiniteStateMachine fsm = FiniteStateMachine.newInstance(None)
    }
    
    class InboundChannelActor extends BaseActor implements InboundChannelState {
    
        public InboundChannelActor(String channelUuid, String destination) {
    
            this.channelUuid = channelUuid
            this.destination = destination
    
            // record a transition for Event: "Parked and All" from State: "None" to State: "Greeting"
            state_ChannelState__fsm.record().on([Parked, All]).from(None).to(None).act = {
                log.info("on Parked from None -> None")
                state_ChannelState__fsm.goToState(state_ChannelState__fsm.currentValue)
            }
    
            // record a transition for Event: "init" on a Greeting, 
            state_ChannelState__fsm.record().on([Init]).from(Greeting).to(Greeting).act = { event ->
                // play greeting
                audioActorService.actorRef.tell(new Shout(channelUuid: channelUuid, audioId: state_ChannelState__fsm.currentValue.greeting.id), context.self())
                // start timer for next action
                akkaService.system.scheduler().scheduleOnce(Duration.create(state_ChannelState__fsm.currentValue.nextStateSeconds, TimeUnit.SECONDS),
                    new Runnable() {@Override public void run() {
    		// go-to next state
                    state_ChannelState__fsm.goToState(new Init(), state_ChannelState__fsm.currentValue.nextState)
                } }, akkaService.system.dispatcher())
            }
    
            // record a transition for Event: "Init" on a Menu
            state_ChannelState__fsm.record().on([Init]).from(Menu).to(Menu).act = { event ->
                // play menu greeting
                audioActorService.actorRef.tell(new Shout(channelUuid: channelUuid, audioId: state_ChannelState__fsm.currentValue.greeting.id), akkaService.actorNoSender())
            }
    
            // record a transition for Event: "KeyPressed" on a Menu,
            state_ChannelState__fsm.record().on([KeyPressed]).from(Menu).to(Menu).act = { event ->
    	    // repeat the keys back to you... 
                speechActorService.actorRef.tell(new Speak(channelUuid: channelUuid, words: "dtmf ${event.digit}"), akkaService.actorNoSender())
            }
    
    	// record a transition for Event: "Hungup" on All transitions... 
            state_ChannelState__fsm.record().on([Hungup]).from(All).to(All).act = { event ->
    	    // stop the Actor
                // todo: stop child actors
                context.stop(context.self())
            }
    
            // Start the Finite State Machine with Configured Action
            state_ChannelState__fsm.goToState(VoiceState.findByE164(destination))
        }	
    }
    

    Lastly... add the Akka onRecieve() method for firing events of to the state machine where we check the transitions registry for a match and "act"

    class InboundChannelActor extends BaseActor implements InboundChannelState {
    	// akka's onRecieve method... fire events to the state machine for this inbound channel instance
    	@Override
    	void onReceive(Object message) throws Exception {
    		state_ChannelState__fsm.fire(message, state_ChannelState__fsm.currentState)
    	}
    }
    

    Groovy & Grails with Akka

    Actors  Akka  Grails  Traits  Actor Model  Groovy  Programming  Technology  FreeSwitch 
    Aug 27, 2014
    Goals:
    1. * Application built to scale up (concurrency)
    2. * Application built to scale out (remoting)
    3. * Avoid race conditions, deadlocks, live locks
    4. * Fault tolerance.

    So the main idea with Actor Model is instead of using shared memory, messages are sent to actors who's state can only be altered by its self. A actor has a mailbox for receiving its messages. When a actor sends a message to a mailbox it's non-blocking. When a actor receives a message in its mailbox its uninterrupted. Actors act on their mailbox messages in order retrospectively.

    Lets dive into a real world example using my PBX demonstration. A call is parked on my freeSwitch. I will send a message to a SwitchBoardActor who's job is to setup up new calls or route existing calls.

    class FreeSwitchConnectionService {
        switchboardActor.tell(parked, akkaService.actorNoSender())
    }
    

    My SwitchBoardActor receives the Parked() message and knows that Parked incoming messages should create a new InboundChannelActor informing it of the Parked message so the newly created InboundChannelActor can setup its' state to receive additional messages.

        class SwitchBoardActor extends UntypedActor implements ActorMaker {
            @Override
            void onReceive(Object message) throws Exception {
                if (message instanceof FreeSwitchEvent && message instanceof Parked) {
                    makeInboundChannelActor(message.channelUuid, message.destination).tell(message, context.self())
                }
            }
        }
    
        class InboundChannelActor extends BaseActor implements ObjectBinding {
            @Override
            void onReceive(Object message) throws Exception {            
                if (message instanceof Parked && !message.variableActor && message.inbound {                
                    // tell freeSwitch to set the variableActor on the freeSwitch channel so the next message get routed to the correct instance of InboundChannelActor
                    freeSwitchActorService.actorRef.tell(copyObject(message, new SetVar(key: "actor", value: self.path().toString())), context.self())
                }
            }
        }
    

    Lets have a look at subsequent messages that have the Actor Uri attached to it. i.e: DTMF events are sent into the Actor System. We decide if we want to do text to speech or play an audio.

        class FreeSwitchConnectionService {
            KeyPressed keyPressed = copyMap(fsEventMap, new KeyPressed())
            switchboardActor.tell(keyPressed, akkaService.actorNoSender())
        }
    
        class SwitchBoardActor extends UntypedActor implements ActorMaker {        
            @Override
            void onReceive(Object message) throws Exception {
                if (message instanceof FreeSwitchEvent && message.variableActor) {
                    getContext().system().actorSelection(message.variableActor).tell(message, context.self())
                }
            }
        }
    
        class InboundChannelActor extends BaseActor implements ObjectBinding {
    
            def akkaService = Holders.applicationContext.getBean("akkaService")
            def freeSwitchActorService = Holders.applicationContext.getBean("freeSwitchActorService")
            def audioActorService = Holders.applicationContext.getBean("audioActorService")
            def speechActorService = Holders.applicationContext.getBean("speechActorService")
            private boolean inputDigitTimerStarted = false
            private inputDigits = []
            
        @Override
            void onReceive(Object message) throws Exception {            
                if (message instanceof KeyPressed) {
                    /* put DTMF digit into an array and start a timer. 
            All digits in the inputDigits array will be used when timer expires.*/
                    inputDigits << message.digit
                    startInputDigitsTimer()
                }
            }
            
            def startInputDigitsTimer(){
                    if (!inputDigitTimerStarted){
                        log.info( " INPUT DIGITS TIMER STARTED ")
                        inputDigitTimerStarted = true
                        akkaService.system.scheduler().scheduleOnce(Duration.create(3, TimeUnit.SECONDS),
                            new Runnable() {
                                @Override
                                public void run() {
                                    def keysPressed = inputDigits.join("").toString()
                                    inputDigits.clear()
                                    log.info(" INPUT DIGITS ARE: $keysPressed")
                                    if (keysPressed.length()) {
                                        if (keysPressed == "1"){
                                            speechActorService.actorRef.tell(new Speak(channelUuid: channelUuid, words: "Welcome" ), context.self())
                                        } else if (keysPressed == "2") {
                                            speechActorService.actorRef.tell(new Speak(channelUuid: channelUuid, words: "Patching you in to com systems" ), context.self())
                                        } else {
                                            audioActorService.actorRef.tell(new Shout(channelUuid: channelUuid, audioId: keysPressed), context.self())
                                        }
                                        inputDigitTimerStarted = false
                                    }
                                }
                            }, akkaService.system.dispatcher()
                        )
                    }
                }
        }
    

    So thats the gist of my actor based PBX. Download the code on GitHub for the full picture.

    You can test drive this code with WebRTC

    Another thing worth noting. I'm using Grails 2.4.3 in this project which includes the latest major release of groovy which implements Traits. In the code above you see my actors implement Traits. Having the ability to do multiple inheritance is a very nice feature. i.e:

    
    trait Channel {
        String channelUuid
        String destination
        String variableActor = null
    }
    
    class FreeSwitchEvent implements Serializable, Channel {
        Boolean inbound = false
        Boolean outbound = false
    }
    
    class Parked extends FreeSwitchEvent {}
    

    It's like pouring in functionality

    trait ObjectBinding {
        def copyObject(source, target) {
            source.properties.each { key, value ->
                if (target.hasProperty(key) && !(key in ['class', 'metaClass', '']))
                    target[key] = value
            }
            return target
        }
    
        def copyMap(Map source, target) {
            source.each{ k, v ->
                try {
                    target[k] = v
                } catch(e){log.error(e.message)}
            }
            return target
        }
    

    I hope you enjoyed this solution. You can clone it here on github...

    I will follow up on this with a fork directly to Scala. I will show you how case class pattern matching, Some/None; greatly reduce the code base.

    Groovy & Grails Rules Engine

    Grails  Rules Engine  Groovy  Programming 
    Aug 10, 2014
    Goals:
    1. * Extendable engine that can be used in any scenario.
    2. * Typeless rules that can be added or removed at runtime. "convention over configuration"
    3. * Decoupled decision that can ask for 1 or more rules engine results.

    Design with a soldier's promotion/demotion implementation

    Lets start with an interface to define the basic contract for a rules engine.

    public interface IRulesEngine {
        def apply(obj)
    }
    

    Here is a concrete base implementation of our rules engine. All of our business derived rules engines will extend this. Methods with the word "Rule" at the end will be executed when calling the apply() method.

    class RulesEngine implements IRulesEngine {
    
        def getRules() {
            def rules = []
            this.class.declaredFields.each {
                def field = this."${it.name}"
                if (!it.isSynthetic() && field instanceof Closure && it.name.endsWith("Rule")) {
                    rules << it.name
                }
            }
            rules
        }
    
        def apply(obj) {
            Set responseSet = [] as Set
            rules.each { rule ->
                responseSet << this."$rule"(obj)
            }
            responseSet
        }
    }
    

    We can start off with 2 engines. Ones which return promotable and demoteable traits.

    class PromotableTraitsRulesEngineService extends RulesEngine {
    
        // example of a rule that returns many traits
        def heroOnBattlefieldRule = { soldier ->
    
            def traits = []
    
            log.info("heroOnBattlefieldRule() ran")
    
            War*.campaigns*.battles.collect { battle -> battle.heros in soldier}.each { battle ->
                traits << """heroOnBattlefield - ${battle.campaign.war} ${battle.campaign}"""
            }
    
            return traits
        }
    }
    
    class DemotableTraitsRulesEngineService extends RulesEngine {
    
        // example of a rule that returns many traits
        def insubordinationOnLeaveRule = { soldier ->
    
            def traits = []
    
            log.info("insubordinationOnLeaveRule() ran")
    
            soldier.leaves.findAll{it.insubordination == true}.each { leave ->
                traits << """insubordinationOnLeave - ${leave.country} ${leave.city} ${leave.place}"""
            }
    
            return traits
        }
    
        // example of a rule that returns 1 traits
        def insubordinationDuringBattleRule = { soldier ->
    
            def traits = []
    
            log.info("insubordinationDuringBattleRule() ran")
    
            def hasInsubordinationDuringBattleRule = War*.campaigns*.battles*.insubordinates.find { insubordinate ->
                insubordinate.soldier == soldier
            }
    
            if (hasInsubordinationDuringBattleRule)
                traits << "insubordinationDuringBattle"
    
            return traits
    
        }
    }
    

    Now we can create a service that aggregates and applies these traits.

    class PromotionRulesEngineService implements IRulesEngine {
    
        def promotableTraitsRulesEngineService
        def demotableTraitsRulesEngineService
    
        def apply( soldier ){
            
            def traits = []
            
            traits << promotableTraitsRulesEngineService.apply( soldier )
            traits << demotableTraitsRulesEngineService.apply( soldier )
            
            return traits
        }
    }
    

    Lets get on to our decision already...

    class PromotionService {
    
        enum Decision {PROMOTE, DEMOTE, NONE, DISHONORABLE_DISCHARGE}
    
        def promotionRulesEngineService
    
        def decide(soldier) {
    
            def traits = promotionRulesEngineService.apply(soldier)
    
            if (traits.collect{it == "insubordinationDuringBattle"}.count())
                return Decision.DISHONORABLE_DISCHARGE
    
            if (traits.collect{it.contains "insubordinationOnLeave"}.count() < 10  
            && traits.collect{it.contains "heroOnBattlefield"}.count() > 0 )
                return Decision.PROMOTE
    
            if (traits.collect{it.contains "insubordinationOnLeave"}.count() > 3  
            && traits.collect{it.contains "heroOnBattlefield"}.count() == 0 )
                return Decision.DEMOTE
    
            return Decision.NONE
        }
    
    }
    
    I hope you enjoyed this solution. You can clone it here on github

    Scala Actors with Traits

    Actors  Traits  Mixins  Scala  Programming 
    Aug 3, 2014
    	case class Heal(item:String)
    	 
    	trait Healing {
    	    val handleHealingMessages = {
    	        case Heal(item) => println("I healed with  " + item)
    	    }
    	}
    
    	case class Eat(item:String)
    
    	trait Eating {
    	    val handleEatingMessages = {
    	        case Eat(item) => println("I ate " + item)
    	    }
    	}
    	 
    	case class Attack(item:String)
    	 
    	class Soldier extends Actor with Healing with Eating {
    
    	    def handleMessages = {
    	        case Attack(item) => println("I'm attacking with my " + item)
    	    }
    	 
    	    def act() = {
    	        loop {
    	            react {			 
    		         /* order matters: if more than one trait handles the same message the first one in
    			 the orElse chain wins.  I want my solder to choose "attack" over healing or eating */
    	                handleMessages orElse handleHealingMessages orElse handleEatingMessages             
    	            }
    	        }
    	    }
    	}
    	 
    	val soldier = new Soldier
    	soldier.start
    	soldier ! Attack("battle riffle")
    	soldier ! Attack("pistol")
    	soldier ! Attack("knife")
    	soldier ! Heal("xstat sponges")
    	soldier ! Eat("field ration")
    	
    

    Autonomous Flight

    Drones  Aerial Footage 
    Aug 2, 2014

    Click here to get your own drone

    Comfortable with Java, but feeling Groovy

    Java  Groovy  Programming  Technology 
    Jul 12, 2014
    def list = ['a','b','a','c','a','a','d','e','d','d','d','d','d']
    

    JAVA

    Map map = new HashMap<>();
    for (T t : list) {
        Integer val = map.get(t);
        map.put(t, val == null ? 1 : val + 1);
    }
    Entry max = null;
    for (Entry e : map.entrySet()) {
    if (max == null || e.getValue() > max.getValue())
        max = e;
    }
    assert 'd' == max.getKey();
    

    JAVAish...

    def m = [:]
    list.each {m[it] = m.get(it,0)+1}
    assert 'd' == m.max{ it.value }.key
    

    GROOVY

    assert 'd' == list.max{Collections.frequency(list, it)}
    

    Longer FPV

    Drones  Technology 
    Jul 11, 2014

    The FPV live video feed to your phone uses 2.4ghz Wifi. Connected to your remote is a small range extender which connects to a camera on the Phantom 2 Vision/+. You can increase your FPV range by upgrading the antennas on your WiFi repeater and/or Vision camera. It's important to note that these upgrades can be done in several phases. Each incrementally increasing your range.

    Upgrading the "pilot side" Wifi repeater


    The following items are needed to perform this upgrade:
    • Electric Drill, Drill Press or a Dremel
    • U.FL Mini PCI to RP-SMA Pigtail Antenna WiFi Cable - available at amazon
    • LHCP 2.4 GHz antenna. I use the LHCP 2.4 GHz Half Sphere Helix 9dBi available at fpvlr.com
    • Industrial strength Velcro
    Open the Wifi repeater by removing the 4 hex screws on the back with an alan wrench.
    Make sure to carefully remove the cover or you will break the connection to the battery.
    Now that you have the repeater open you should be able to find the connection for the 2 internal antennas. You can upgrade 1 or both of them.
    Drill a hole in the cover of the Wifi repeater so that you can mount the RP-SMA Pigtail antenna to the extender and replace the internal antenna. You can leave the internal antenna inside of the Wifi repeater.

    Reassemble the Wifi repeater. Affix velcro to the top side of the Wifi Repeter and the bottom side of your LHCP antenna and attach the antenna to the newly installed RP-SMA Pigtail.

    Now your FPV should be doubled by upgrading "pilot side" internal antenna's.

    Upgrading the "phantom side" Wifi

    The phantom drone has 2 antennas located inside the camera which provide FVP via 2.4ghz Wifi. The Wifi repeater on your remote makes a connection to the camera via these antennas.
    You will need to open up your camera with a allen wrench and replace 1 or both antennas.
    Drill a hole in the back of the camera case and run a U.FL Mini PCI to RP-SMA Pigtail Antenna WiFi Cable. There are 2 screws on either side of the lens. Loosen those a bit so that a bit of play between the main-board and antenna mounts is available.
    Remove the stock antenna mini pci connection.
    Attach the newly installed mini pci to rp-sma cable to the main-board.
    Tighten your camera lens mount screws.
    Reassemble your camera.

    Now you need to mount the newly installed antenna cable to the drone. I used my dremel to shape a child safety cabinet lock into a mount and attached it into the leg of the vision.


    Upgrading Complete!!!


    I now enjoy between 800-1500 meters depending on my flight environment.

    You might have noticed I have a pilot side remote antenna upgrade. I will update this post with the 5.8ghz remote "pilot/driver" upgrades soon...

    Happy Flying!

    Click here to get your own drone