Yay! I got it to work.
Here is what I did:
1) On the pi start an application called RegisterJarExample that was made into
a runnable jar file.
package pi;
...
public class RegisterJarExample {
public static void main(String args[]) throws Exception {
String s = null;
for (String str: args) {
s = str;
}
/* a device configuration file ties a specific device
* to a device type and an organization
* each device needs an authentication token
* devices must be registered at IOT prior to running this
application
*/
File configFile;
if (s != null) {
s = "./" + s;
configFile = new File(s);
} else {
configFile = new File("./device_config.txt");
}
IotProvider provider = new IotProvider(topology -> new
IotfDevice(topology, configFile));
provider.start();
}
}
java -jar RegisterJar.jar
2) I placed the jar file that will be registered via the Edgent registerJar
command on the pi (note this could be some external URL, but for my example I
just uploaded it to the pi).
I called the jar file pi.sensors.jar.
To build the jar file, my build file looked like this:
<project name="pi.sensors" default="registerJar">
<target name="registerJar">
<jar destfile="bin/pi.sensors.jar">
<service type="org.apache.edgent.topology.services.TopologyBuilder">
<provider classname="pi.sensors.SpeedSensorTopologyBuilder$SpeedSensor"
/>
</service>
<fileset dir="./bin" includes="**/SpeedSensorTopologyBuilder*"/>
</jar>
</target>
</project>
The SpeedSensorTopologyBuilder class looks like this:
public class SpeedSensorTopologyBuilder {
private static abstract class Sensor implements TopologyBuilder {
@Override
public BiConsumer<Topology, JsonObject> getBuilder() {
return (topology,config) ->
SpeedSensor.myIotDeviceBasedBuilder(IotDevicePubSub.addIotDevice(topology),
config);
}
}
public static class SpeedSensor extends Sensor {
@Override
public String getName() {
return "SpeedJarApp";
}
public static void myIotDeviceBasedBuilder(IotDevice iotDevice,
JsonObject config) {
TStream<Date> readingTime = iotDevice.topology().poll(() -> new
Date(), 3, TimeUnit.SECONDS);
TStream<JsonObject> speedReading = readingTime.map(rt ->
{
JsonObject speedInfo = new JsonObject();
long curTime =
System.currentTimeMillis();
SimpleDateFormat sdf = new
SimpleDateFormat("MMM dd,yyyy HH:mm:ss");
Date dateObj = new Date(curTime);
speedInfo.addProperty("time:",
sdf.format(dateObj));
try {
double speed =
SystemInfo.getMemoryUsed() * 0.0000000752;
Random randomGenerator = new
Random();
int randomInt =
randomGenerator.nextInt(20);
double randSpeed = speed +
randomInt;
DecimalFormat df = new
DecimalFormat("#.##");
speedInfo.addProperty("Speed",
df.format(randSpeed));
} catch(Exception e) {
throw new RuntimeException(e);
}
return speedInfo;
});
speedReading.print();
iotDevice.events(speedReading, "speedReading",
QoS.FIRE_AND_FORGET);
}
}
}
3. I issued this registerJar command to the pi:
{"args":["file:/home/pi/slcEdgent/pi.sensors.jar",""],"op":"registerJar","alias":"edgent","type":"appService”}
4. I issued the ‘submit’ command:
{"args":["SpeedJarApp",{}],"op":"submit","alias":"edgent","type":"appService”}
In the running application on the pi, I saw this line:
Mar 31, 2017 12:34:58 AM pi.sensors.SpeedSensorTopologyBuilder$SpeedSensor
myIotDeviceBasedBuilder
and then these lines:
{"time:":"Mar 31,2017 00:36:49","Speed":"15.12"}
{"time:":"Mar 31,2017 00:36:52","Speed":"23.13”}
5. Finally, I stopped the running application by issuing the ‘CLOSE’ command:
{"args":["CLOSE"],"op":"stateChange","alias":"SpeedJarApp","type":"job”}
The output on the pi stopped.
Thanks a bunch for your help Dale!
Cheers,
Susan
> On Mar 30, 2017, at 7:19 AM, Dale LaBossiere <[email protected]> wrote:
>
>> On Mar 28, 2017, at 12:40 PM, Susan Cline <[email protected]> wrote:
>> ...
>> I have not gotten back to this since Dale posted this a long time ago, but
>> I’d like to get this working.
>
> I’ve reread all of this thread - whew :-). I think you’re very close. Your
> jar is OK. The registerJar cmd worked. The submit cmd worked (with your
> getBuilder() that returned a fn that just created a top that printed the app
> name).
>
> I’ll stick with the assertion in my last msg of 9/26 11:24. I think all
> that's left to fix is:
>
> - change your TopologyBuilder.getBuilder() impl
> from
> (t, c) -> buildTopology(t, c)
> to
> (t, c) -> buildTopology( IotDevicePubSub.addIotDevice(t), c))
> Notice that’s exactly what IotProvider.registerTopology() does - how
> the IotDevice will get created for and passed to your builder/top
>
> - change your buildTopology(Topology t, JsonConfig c) to
> buildTopology(IotDevice iotDevice, JsonConfig c) <== just a rename of
> the accept() in your 9/16/1:17 mail
>
> I’m going to add a JIRA and improve the doc in IotProvider to make this clear.
> — Dale