Loosely-coupled Component Infrastructure Using LooCI Contiki / OSGi / Android 1 Structure Programming LooCI OSGi LooCI Contiki Setup of environment Assignment 2 To start Copy the virtual machine from USB stick on your drive Get, install & open virtual box or vm software Download Ask for the USB stick containing executables Import the loociVM into your virtual machine : file -> import appliance -> select appliance -> select the copy -> next -> next. Password of VM is ‘user’ 3 To Start Make sure that the VM network is set to “bridged adaptor” Settings -> network Or ctrl+s while in VM -> network -> adaptor1 Or devices -> network adaptors To change keyboard if required: 1) Click on the icon placed at the top right corner. 2) Click on System Settings 3) Click on Keyboard icon 4) Click on Layout Setting label. 5) Add your language in the layout tab and put it as the first one in the list. 4 LooCI OSGi Component = OSGi bundle loociOsgi workspace : home/user/looci/looci.osgi To create a new component: Create new plug-in project Add LooCI services as dependency & required bundle in metaInf Activator must extend the LoociComponent class • At meta-inf set activator to your component class To create jar: Copy a build.xml file from another component (several present in osgi) Adjust name of project Do ant build in eclipse file “projectName.jar” in felix/looci/comps -> local component repository Deploy : in gui : “deploy projectName.jar nodeIP osgi” 5 OSGi : Declaring codebase public class LoociSensor extends LoociCodebase { public LoociSensor () { super("Sensordisplay", new short[] {EventTypes.TEMP_READING}, new short[] {}); } @Override public ILoociInstance createLoociComponent() { return new LoociSensorInstance(); } // component name //provided temp //nothing required //abstract factory pattern } 6 OSGi : Declaring component public class LoociSensorComponent extends LoociComponent implements ITimeListener { private LoociTimer timer; public void componentStart() { timer = new LoociTimer(this, 20, true); rand = new Random(); timer.start(); } public void componentStop() { timer.stop(); } 7 OSGi: Declaring component: Sending events @Override public void receive(short eventID, byte[] payload) { // do nothing, this is event producer } @Override public void doOnTimeEvent(LoociTimer expiredTimer) { //callback for timer interface byte val = (byte)rand.nextInt(); //random value publish(EventTypes.TEMP_READING, new byte[]{val}); } } 8 OSGi: Declaring component Receiving event & print it out @Override public void receive(short eventID, byte[] payload) { if(eventID == EventTypes.TEMP_READING){ System.out.println(“received temp: “+ payload[0]); } } 9 LooCI Contiki Create folder in component directory Copy / create makefile Easiest => copy from existing project and rename projectname in make file and c and header file (copy a-testcomponent folder) Make sure link to looci is correct, can change due to path To declare component: C Macros To create a component: Go to the contiki component folder • /home/user/looci/looci.contiki/looci/applications/ Enter : ‘make copy’ • Potentially requires root in some cases, pw = user • Automatically puts file in component repository (if makefile.component set) To deploy: use gui and name the component file 10 Contiki: Sending/ receiving #define INT_TEMP_EVENT 402 #define PROPERTY_ID_INTERVAL 1 struct state{struct etimer et;uint8_t interval;}; static struct state initVar PROGMEM = {.interval = 10}; #define LOOCI_COMPONENT_NAME temp_sample #define LOOCI_NR_PROPERTIES 1 LOOCI_PROPERTIES({PROP_TIME_INTERVAL,DATATYPE_BYTE,offsetof(struct state,interval),1,name}); COMPONENT_INTERFACES(INT_TEMP_EVENT ); COMPONENT_NO_RECEPTACLES(); LOOCI_COMPONENT_INIT("Temp Sampling",struct state,&initVar); 11 Contiki: Sending/ receiving static uint8_t activate(struct state* compState, void* data){ ETIMER_SET(&compState->et, compState->interval * CLOCK_SECOND); return LC_SUCCESS; } static uint8_t time(struct state* compState, void* data){ uint8_t temp = rng(); PUBLISH_EVENT(TEMP_EVENT, (uint8_t*)&temp, sizeof(temp)); ETIMER_RESET(&compState->et); return LC_SUCCESS; } COMP_FUNCS_INIT //THIS LINE MUST BE PRESENT COMP_FUNC_ACTIVATE(activate) COMP_FUNC_TIMER(time) COMP_FUNCS_END(NULL)//THIS LINE MUST BE PRESENT 12 LooCI Gui overview Gui Simple Gui to manage LooCI platforms Enter commands, receive feedback List of commands : enter “help” More info on command enter “help commandName” For more information : slides in the back No access control in these VM’s Please be careful not to mess up other people’s configurations When working with android device, only do wires, or ask for us !! 13 Exercises: Exercise 1: receive temp, filter, forward, press button, do buzz Deploy the necessary components Instantiate & wire all components Activate components -> should produce beep Exercise 2: Write a forward temperature on button press component Deploy & wire instead of the previous components Result should be the same Exercise 3: Write a button press component for OSGi On button press on your local machine / android device -> avr buzzes 14 Exercise 1: Setup to realize OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor TempFilter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 15 Overview of addresses and ID’s Your backend IP: aaab::XY (e.g. aaab::2 / aaab::12) Your back-end component: codebase ID = 10, component ID = 10 tutorialButtonComp: codebase ID = 11, component ID = 11 Your node IP: nodeXY (e.g. node2 / node12) Temp filter : Button sensor: Buzzer : ButtonTempCounter: codebase ID = 2, component ID = 10 codebase ID = 3, component ID = 11 codebase ID = 4, component ID = 12 codebase ID = 5, component ID = 13 Temp producer : nodeBC Temp producer component: codebase ID = 2, component ID = 10 • Please do not touch this node Please: only use your own nodes 16 Start environment Import VM, set network settings to bridged adaptor Start VM Each of you must receive a unique numbered node: nr is XY Initiate your IP address with the correct number Double click the setup icon The user password is asked • Enter ‘user’ Your number is asked • Enter your own number • (Will keep asking for number until valid number is entered) 17 Start LooCI Start LooCI gui Double click on loociGui icon on desktop Open eclipse environments (icon on desktop) : /home/user/looci/looci.contiki workspace should be selected Alternatively you can work in command line and use text editor /home/user/looci/looci.contiki/looci/applications/tutorialComponents/ /home/user/looci/looci.osgi/LoociComponents/ You now have a working environment and should be able to ping the nodes: In gui enter ‘ping nodeXY’ with XY your number » Enter ‘help’ for list of commands » Enter ‘ls’ to see list of available components 18 At end Please click the end icon when you finish This sends the log file containing the trace of your gui This allows us to view where common mistakes were made No personal info is in these files We identify by node number Feel free to check 19 1a Deploy the back-end After starting LooCI OSGi, the LooCI gui should appear Deploy and activate your backend component “deploy tutorialBackend.jar aaab::XY osgi” • Deploys your backend component • Should return codebaseID 10 “instantiate 10 aaab::XY” • Creates component instance of backend – a window should appear on your screen • Should return componentID 10 “activate 10 aaab::XY” • Activates your backend XY is the number of the node you are assigned 20 1b Instantiate and wire Now, instantiate all the components on your node We already deployed the necessary components to your node Afterwards you will deploy your own component ‘instantiate 2 nodeXY’ -> returns componentID 10 This instantiates the temp filter ‘instantiate 3 nodeXY’ -> returns componentID 11 This instantiates the button sensor ‘instantiate 4 nodeXY’ -> returns componentID 12 This instantiates the buzzer component 21 1b Perform wirings on node ‘wireFrom temp_ev 0 nodeBC 10 nodeXY’ Send temp events from sensor node broadcaster to filter ‘wireTo temp_ev 10 nodeXY aaab::XY’ Send temp events from filter to your backend ‘wireTo button_ev 11 nodeXY aaab::XY’ Send button press events from your node to your backend ‘wireFrom buzz_ev 0 :: 12 nodeXY’ Deliver buzz events from any address to component 12 on your node 22 1b Perform wirings backend ‘wireFrom temp_ev 0 nodeXY 10 aaab::XY’ Deliver temp events from your node to component 10 ‘wireFrom button_ev 0 nodeXY 10 aaab::XY’ Deliver button events from your node to component 10 ‘wireTo buzz_ev 10 aaab::XY nodeXY’ Send buzz events from your backend to your node 23 1c Activate components ‘activate 10 nodeXY’ Activates the temp filter ‘activate 11 nodeXY’ Activates the button sensor ‘activate 12 nodeXY’ Activates the buzzer => press button on avr, you should see on your OSGi interface that an event comes in, and that it sends out a new buzz event. If it does not work : check wires & state of all components Do ‘getState 10 nodeXY’ to see if component 10 is active (returns 1) To view the setup, enter ‘draw nodeXY’ in the gui This shows the current wirings on your avr raven node » NOTE: visualizer is still in beta, so might not be perfect 24 Exercise 1: Setup realized OSGi NODE: aaab::XY NODE: nodeXY Buzzer Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 ButtonSensor TempFilter Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 25 1d Play around Change the wires and the properties a bit, see how it affects your composition. For example: set temp filter property Get lower bound of temp filter • getProperty 1 10 node1 byte – Should return 0 Set property to 100 => should not allow any more events • setProperty 1 10 node1 100 byte Please be careful and do not interrupt the nodes of others 26 1e Deactivate Deactivate temp filter ‘deactivate 10 nodeXY ‘ • deactivate temp filter ‘deactivate 12 nodeXY ‘ • Deactivate buzzer 27 Setup to realize exercise 2 OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor ButtonTemp Counter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 28 Exercise 2 Create a buttonTempCounter Create a component that allows a temperature event to pass for each time you press the button Go to your Contiki eclipse environment (or other editor) Looci contiki path/workspace : /home/user/looci/looci.contiki/looci Component subfolder : applications/tutorialComponents/buttonTempCounter Go to: applications/tutorialComponents/buttonTempCounter/ Open buttonTempCounter.c Write the necessary code to do the following: If the button is pressed, you increment the nrToSend If the temp reading comes in, and nrToSend > 0, then publish the temp reading again, and decremetn nrReads Note, the nrReads is already a property in the example You can check the tempSample and buttonSensor projects for aid 29 2b Build and copy Once you made your component you can build it Open a linux terminal and go to /looci/looci.contiki/looci/applications/tutorialComponents/buttonTempCounter Enter “sudo make copy” -> this creates the component file if all goes well The component is copied in the looci component repository Do “ls” in LooCI Gui • This should show that you now have a new component there Now you have put the component in the LooCI component repository, from which you can easily deploy it 30 2c Deploy and wire Go back to your gui, and deploy and wire the component ‘ deploy buttonTempCounter.comp nodeXY raven ‘ • Returns codebaseID 5 ‘instantiate 5 nodeXY ‘ • Returns componentID 13 ‘ wireFrom temp_ev 0 nodeBC 13 nodeXY ‘ ‘ wireLocal button_ev 11 13 nodeXY ‘ ‘ wireTo temp_ev 13 nodeXY aaab::XY ‘ ‘ activate 13 nodeXY ‘ Component is now activated and should be running 31 2d Using properties Press the button a few times Do ‘getProperty 1 13 nodeXY byte’ • This returns the number of reads the component still has to do • Wait a bit, do it again, see it decrease Do ‘setProperty 1 13 nodeXY 5 byte’ • Now you tell the component to let 5 readings through 32 Setup realized exercise 2 OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor ButtonTemp Counter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 33 Exercise 2: Learned lessons This exercise showed the following The deployment interface between osgi and raven is identical Changing internal configuration on raven did not affect the backend • Easy adaptation of internal configuration Changing component state very straight forward Creating and integrating new components in the event flow Property and events work seamless You can do ‘draw nodeXY’ Shows you the new component composition • Remember, visualizer is still in beta 34 Exercise 3: Make buzzer go off You will create an OSGi component, that sends out a button event. In the first instance, this button event will be wired to the back-end component, which will then send out a buzz event Switch eclipse to osgi workspace Go to OSGi workspace: project comp_tutorialButtonSender. Open the buttonSenderComponent File -> switch workspace -> /home/user/looci/looci.osgi Or location: /home/user/looci/looci.osgi/LoociComponent/ButtonSender 35 Setup to realize exercise 3 OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor ButtonTemp Counter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Btn_ev Ev = 401 Temp_ev Ev = 402 ButtonSend Component Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 36 3b Implement in OSGi What you must do is make it publish a buttonEvent Implement the relevant method. In the folder is an ant build file. Execute the build file Right click on build.xml, Or do ‘ant’ in the right folder in terminal This automatically puts the component jar in the component folder. Deploy, and wire the button press component to your back-end server This is a wireLocal command !! 37 3c Deploy and wire Commands: ‘deploy tutorialButtonSender.jar aaab::XY osgi’ -> codebaseId 11 ‘instantiate 11 aaab::XY’ -> componentID 11 ‘wireLocal button_ev 11 10 aaab::XY’ ‘activate 11 aaab::XY’ Activate the buzzer again to hear buzzes: ‘activate 12 nodeXY’ Now if you press the button on your gui, the buzzer goes Deactivate buzzer again ‘deactivate 12 nodeXY’ 38 Exercise 4 : Do a temp reading on button press in gui Concept, we only take a temp reading if we press a button Send the button press event from back-end to node wireTo button_ev 11 aaab::XY nodeXY Deliver button press event from back_end to component on node wireFrom button_ev 0 aaab::XY 13 nodeXY Extra: Wire the tempFilter component on Contiki between the buttonTempSender and the buttonTempCounter component 39 Setup to realize exercise 4 OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor ButtonTemp Counter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Btn_ev Ev = 401 Temp_ev Ev = 402 ButtonSend Component Btn_ev Ev = 401 Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 40 Exercise 5: Write a temp filter You have seen how to write new components in contiki and osgi Now write an osgi component almost from scratch It must filter temp events before being shown on the screen It receives temp events, checks whether they’re inside the boundaries and publishes them. To start: Open the Comp_TutorialFilter project Declare provided and required interfaces in LoociFilter.java Create necessary properties Write filter logic in the receive method, and publish the event if it matches Execute the ant build in eclipse 41 Setup to realize exercise 5 OSGi NODE: aaab::XY NODE: nodeXY Buzzer ButtonSensor ButtonTemp Counter Buzz_ev Ev = 403 Tutorial Back-end Btn_ev Ev = 401 Temp Filter Temp_ev Ev = 402 Btn_ev Ev = 401 ButtonSend Component Btn_ev Ev = 401 Sensor node TempSensor Gateway Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1 42 5b Deploy and wire filter Insert the tempfilter between the back-end component and the remote node Remove existing wire from remote node to back-end component at back-end (unwireFrom) Wire your buttonTempCounter remote component to the filter (wireFrom) Wire the filter component to the back-end component (wireLocal) Don’t forget to activate the components 43 Exercise 6 : Use adroid as button and to log Concept: add a wireless android device to the setup !!Ask for the android IP address and component to use !! Connect your unique component on the android device to your node. If button is pressed, a temperature reading is taken You can also send out the button to your back-end => buzzer Wire the temperature also to the correct OSGi component on android Be carefull, android is a shared resource 44 Lessons Learned Homogeneous interface for heterogeneous devices Software development in two languages, yet they interact the same Distributed event bus Changes on one node do not necessarily influence changes on another Clashes are possible though !! Properties and events work seamless together Limited overhead to create new behaviour 45 Questions? For any other questions with regards to LooCI: Architecture/collaborations : danny.hughes@cs.kuleuven.be Contiki/Osgi : jef.maerien@cs.kuleuven.be SunSPOT : klaas.thoelen@cs.kuleuven.be Android : rafael.bachiller@cs.kuleuven.be 46 Relevant commands Command Arguments: (also available in gui by entering ‘help’) deploy file - address - nodetype removeCodebase codebase id - address Instantiate codebase id - address destroyComponent component id - address Activate component id - address deactivate component id - address wireLocal event id - src component id - dst component id - address unwireLocal event id - src component id - dst component id - address wireFrom event id - src comp id - src address - dst comp id - dst addr unwireFrom event id - src comp id - src addr - dst comp id - dst addr wireTo event id - src component id - dst address - src address unwireTo event id - src component id - dst address - src address resetWires component id - address setProperty property id - comp id - addr - prop value - prop type 47 Relevant commands (2) getComponentsOfCodebase codebase id - address getCodebaseName codebase id - address getCodebaseIDOfComponent component id - address getCodebaseNameOfComponent component id - address getComponentIDs address getState component id - address getProvidedInterfaces component id - address getRequiredInterfaces component id - address getLocalWires event id - src component id - dst component id - address getWiresTo event id - src component id - dst address - address getWiresFrom event id - src comp id - src addr - dst comp id - dst addr getProperties component id - address getProperty property id - component id - address - property type getPropertyInfo property id - component id - address getPlatformType address 48 Relevant node addressing NodeBC -> broadcast node Aaab::xy -> your own back-end nodeXY -> node as defined in hosts file Please make sure you only user your own nodes 49 Relevant event types button_ev temp_ev buzz_ev 401 402 403 Relevant properties: We only used propertyId 1 to make it easy for everyone For filtering we propose to use propertyId 1 for the lower boundary and 2 for the upper boundary 50