500 likes | 739 Views
Loosely-coupled Component Infrastructure Using LooCI Contiki / OSGi / Android. Structure . Programming LooCI OSGi LooCI Contiki Setup of environment Assignment. To start . Copy the virtual machine from USB stick on your drive Get, install & open virtual box or vm software Download
E N D
Loosely-coupled Component Infrastructure Using LooCI Contiki / OSGi / Android
Structure • Programming • LooCI OSGi • LooCI Contiki • Setup of environment • Assignment
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’
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.
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 nodeIPosgi”
OSGi : Declaring codebase public class LoociSensor extends LoociCodebase { public LoociSensor () { super("Sensordisplay", // component name new short[] {EventTypes.TEMP_READING}, //provided temp new short[] {}); //nothing required } @Override public ILoociInstancecreateLoociComponent() { return new LoociSensorInstance(); //abstract factory pattern } }
OSGi : Declaring component public class LoociSensorComponent extends LoociComponent implementsITimeListener { private LoociTimer timer; public void componentStart() { timer = new LoociTimer(this, 20, true); rand = new Random(); timer.start(); } public void componentStop() { timer.stop(); }
OSGi: Declaring component:Sending events @Override public void receive(short eventID, byte[] payload) { // do nothing, this is event producer } @Override public void doOnTimeEvent(LoociTimerexpiredTimer) { //callback for timer interface byte val = (byte)rand.nextInt(); //random value publish(EventTypes.TEMP_READING, new byte[]{val}); } }
OSGi: Declaring componentReceiving event & print it out @Override public void receive(short eventID, byte[] payload) { if(eventID == EventTypes.TEMP_READING){ System.out.println(“received temp: “+ payload[0]); } }
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
Contiki: Sending/ receiving #define INT_TEMP_EVENT 402 #define PROPERTY_ID_INTERVAL 1 struct state{structetimer 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(structstate,interval),1,name}); COMPONENT_INTERFACES(INT_TEMP_EVENT ); COMPONENT_NO_RECEPTACLES(); LOOCI_COMPONENT_INIT("Temp Sampling",structstate,&initVar);
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
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 !!
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
Exercise 1: Setup to realize OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Tutorial Back-end Buzzer Btn_ev Ev = 401 ButtonSensor Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc TempFilter Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
Overview of addresses and ID’s • Your backendIP: 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 nodeIP: nodeXY(e.g.node2 / node12) • Temp filter : codebase ID = 2, component ID = 10 • Button sensor: codebase ID = 3, component ID = 11 • Buzzer : codebase ID = 4, component ID = 12 • ButtonTempCounter: 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
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)
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
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
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
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
1b Perform wirings on node • ‘wireFromtemp_ev 0 nodeBC 10 nodeXY’ • Send temp events from sensor node broadcaster to filter • ‘wireTotemp_ev 10 nodeXYaaab::XY’ • Send temp events from filter to your backend • ‘wireTobutton_ev 11 nodeXYaaab::XY’ • Send button press events from your node to your backend • ‘wireFrombuzz_ev 0 :: 12 nodeXY’ • Deliver buzz events from any address to component 12 on your node
1b Perform wirings backend • ‘wireFromtemp_ev 0 nodeXY 10 aaab::XY’ • Deliver temp events from your node to component 10 • ‘wireFrombutton_ev 0 nodeXY 10 aaab::XY’ • Deliver button events from your node to component 10 • ‘wireTobuzz_ev 10 aaab::XY nodeXY’ • Send buzz events from your backend to your node
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
Exercise 1: Setup realized OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Tutorial Back-end Buzzer Btn_ev Ev = 401 ButtonSensor Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc TempFilter Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
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
1e Deactivate • Deactivate temp filter • ‘deactivate 10 nodeXY ‘ • deactivate temp filter • ‘deactivate 12 nodeXY ‘ • Deactivate buzzer
Setup to realize exercise 2 OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Buzzer Tutorial Back-end Btn_ev Ev = 401 ButtonSensor Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc ButtonTempCounter Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
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) • Loocicontiki 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 decremetnnrReads • Note, the nrReads is already a property in the example • You can check the tempSample and buttonSensor projects for aid
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
2c Deploy and wire • Go back to your gui, and deploy and wire the component • ‘ deploy buttonTempCounter.compnodeXY raven ‘ • Returns codebaseID 5 • ‘instantiate 5 nodeXY ‘ • Returns componentID 13 • ‘ wireFromtemp_ev 0 nodeBC 13 nodeXY ‘ • ‘ wireLocalbutton_ev 11 13 nodeXY ‘ • ‘ wireTotemp_ev 13 nodeXYaaab::XY ‘ • ‘ activate 13 nodeXY ‘ • Component is now activated and should be running
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
Setup realized exercise 2 OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Buzzer Tutorial Back-end Btn_ev Ev = 401 ButtonSensor Temp_ev Ev = 402 XY = pcNr 01, 02, 03, 10, 11, etc ButtonTempCounter Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
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
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
Setup to realize exercise 3 OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Buzzer Tutorial Back-end Btn_ev Ev = 401 ButtonSensor Btn_ev Ev = 401 Temp_ev Ev = 402 ButtonTempCounter ButtonSendComponent Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
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 !!
3c Deploy and wire • Commands: • ‘deploy tutorialButtonSender.jar aaab::XY osgi’ -> codebaseId 11 • ‘instantiate 11 aaab::XY’ -> componentID 11 • ‘wireLocalbutton_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’
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 • wireTobutton_ev 11 aaab::XY nodeXY • Deliver button press event from back_end to component on node • wireFrombutton_ev 0 aaab::XY 13 nodeXY • Extra: • Wire the tempFilter component on Contiki between the buttonTempSender and the buttonTempCounter component
Setup to realize exercise 4 OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Buzzer Tutorial Back-end Btn_ev Ev = 401 ButtonSensor Btn_ev Ev = 401 Temp_ev Ev = 402 ButtonTempCounter ButtonSendComponent Btn_ev Ev = 401 Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
Exercise 5: Write a temp filter • You have seen how to write new components in contiki and osgi • Now write an osgicomponent 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
Setup to realize exercise 5 OSGi NODE: aaab::XY NODE: nodeXY Buzz_ev Ev = 403 Buzzer Tutorial Back-end Btn_ev Ev = 401 ButtonSensor Btn_ev Ev = 401 Temp Filter Temp_ev Ev = 402 ButtonTempCounter ButtonSendComponent Btn_ev Ev = 401 Sensor node Gateway TempSensor Temp_ev Ev = 402 nodeBC Aaaa::1 Aaab::1
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
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
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
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
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 - dstaddr • unwireFrom event id - src comp id - srcaddr - dst comp id - dstaddr • 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
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 - srcaddr - dst comp id - dstaddr • getProperties component id - address • getProperty property id - component id - address - property type • getPropertyInfo property id - component id - address • getPlatformType address
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
Relevant event types • button_ev 401 • temp_ev 402 • buzz_ev 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