Hi Dennis, great question. I do all my development for Iota using the IntelliJ
community edition so there is a Mac development environment and it works well.
One thing that I have been thinking about but haven’t gotten around to is
producing a video that would show you how to setup an Intellij environment
download iota and start developing iota performers using Scala/Akka. You can
run the iota engine on devices as small as a Raspberry or as large as a Mesos
cluster. That’s we we do at Litbit. Here is an example of what you would use
Intellij to output
1) a set of jar files one for each performer
2) An orchestration which is essentially the network of interacting performers
You could run this on any JVM
Here are some examples of orchestrations (Performers not included)
Here is test orchestration that shows a single performer that is configured to
consume from a Kafka cluster - The orchestration doesn’t connect it to anything
so it doesn’t do much.
{
"guid" : "KAFKA-CONSUMER-10",
"command" : "CREATE",
"timestamp": "21326329079",
"name" : "ORCHESTRATION FOR TEST",
"ensembles" : [
{
"guid":"KAFKA-CONSUMER-ENS",
"command": "NONE",
"performers":[
{
"guid": "KAFKA-PERFORMER-10",
"schedule": 0,
"backoff": 0,
"autoScale": 4,
"source": {
"name": "fey-kafka-10.jar",
"classPath": "org.apache.iota.fey.performer.Kafka_Consumer",
"parameters": {
"topic":"test-10p",
"consumer_number": "2",
"kafka_properties":"{\"bootstrap.servers\": \"localhost:9092\",
\"key.deserializer\":
\"org.apache.kafka.common.serialization.StringDeserializer\",
\"value.deserializer\":\"org.apache.kafka.common.serialization.StringDeserializer\"}"
}
}
}
],
"connections":[]
}
]
}
Here is a more complex orchestration that runs on a RaspberryPi. It takes the
input of many sensors and send them to a ZMQ performer that publishes them. It
could equally have been an MQTT or ActiveMQ performer
{
"guid": "MAESTRO-3",
"command": "RECREATE",
"timestamp": "7919767890",
"name": "DESCRIPTION",
"ensembles": [
{
"guid": "TEMPERATURE",
"command": "NONE",
"performers": [
{
"guid": "Heartbeat",
"schedule": 30000,
"backoff": 0,
"source": {
"name": "fey_stream.jar",
"classPath": "org.apache.iota.fey.performer.Heartbeat",
"parameters": {
}
}
},
{
"guid": "Cherry",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry": "{\"op\":\"cov\",
\"args\":[{\"string\":\"1ed6aed2b028486fa478b3d3f6e7ee61\"}, {\"float\":0.5}
]}",
"lrns": "[\"1ed6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Heartbeat": [
"Cherry"
]
},
{
"Cherry": [
"ZMQPublisher"
]
}
]
},
{
"guid": "PRESSURE",
"command": "NONE",
"performers": [
{
"comment": "This forces a value to be output every 10 seconds",
"guid": "Heartbeat",
"schedule": 10000,
"backoff": 0,
"source": {
"name": "fey_stream.jar",
"classPath": "org.apache.iota.fey.performer.Heartbeat",
"parameters": {
}
}
},
{
"comment": "The Cherry checks to see if it should output something
every 1 second",
"guid": "Cherry",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey-cherry-rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry": "{\"op\":\"cov\",
\"args\":[{\"string\":\"3fd7aed2b028486fa478b3d3f6e7ee61\"}, {\"float\":0.1}
]}",
"lrns": "[\"3fd7aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Heartbeat": [
"Cherry"
]
},
{
"Cherry": [
"ZMQPublisher"
]
}
]
},
{
"guid": "HUMIDITY",
"command": "NONE",
"performers": [
{
"guid": "Heartbeat",
"schedule": 30000,
"backoff": 0,
"source": {
"name": "fey_stream.jar",
"classPath": "org.apache.iota.fey.performer.Heartbeat",
"parameters": {
}
}
},
{
"guid": "Cherry",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry": "{\"op\":\"cov\",
\"args\":[{\"string\":\"2fd6aed2b028486fa478b3d3f6e7ee61\"}, {\"float\":5.0}
]}",
"lrns": "[\"2fd6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Heartbeat": [
"Cherry"
]
},
{
"Cherry": [
"ZMQPublisher"
]
}
]
},
{
"guid": "SOUNDDB",
"command": "NONE",
"performers": [
{
"guid": "Heartbeat",
"schedule": 10000,
"backoff": 0,
"source": {
"name": "fey_stream.jar",
"classPath": "org.apache.iota.fey.performer.Heartbeat",
"parameters": {
}
}
},
{
"guid": "Cherry",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry": "{\"op\":\"cov\",
\"args\":[{\"string\":\"7fd6aed2b028486fa478b3d3f6e7ee61\"}, {\"float\":3.0}
]}",
"lrns": "[\"7fd6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Heartbeat": [
"Cherry"
]
},
{
"Cherry": [
"ZMQPublisher"
]
}
]
},
{
"guid": "VIBRATION_AGGREGATE",
"command": "NONE",
"performers": [
{
"guid": "Heartbeat",
"schedule": 10000,
"backoff": 0,
"source": {
"name": "fey_stream.jar",
"classPath": "org.apache.iota.fey.performer.Heartbeat",
"parameters": {
}
}
},
{
"guid": "Cherry",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry": "{\"op\":\"cov\",
\"args\":[{\"string\":\"5fd6aed2b028486fa478b3d3f6e7ee61\"}, {\"float\":0.02}
]}",
"lrns": "[\"5fd6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Heartbeat": [
"Cherry"
]
},
{
"Cherry": [
"ZMQPublisher"
]
}
]
},
{
"guid": "VIBRATION",
"command": "NONE",
"performers": [
{
"guid": "VibrationStream",
"schedule": 1000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry":
"{\"didVibrationChange\":\"6fd6aed2b028486fa478b3d3f6e7ee61\"}",
"lrns": "[\"6fd6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"VibrationStream": [
"ZMQPublisher"
]
}
]
},
{
"guid": "SOUND_WAV",
"command": "NONE",
"performers": [
{
"guid": "Cherry",
"schedule": 3000,
"backoff": 0,
"source": {
"name": "fey_cherry_rp.jar",
"classPath": "org.apache.iota.fey.performer.CherryRP",
"parameters": {
"cherry":
"{\"didSoundChange\":\"9fd6aed2b028486fa478b3d3f6e7ee61\"}",
"lrns": "[\"9fd6aed2b028486fa478b3d3f6e7ee61\"]",
"host": "192.168.0.17"
}
}
},
{
"guid": "ZMQPublisher",
"schedule": 0,
"backoff": 0,
"source": {
"name": "fey_zmq.jar",
"classPath": "org.apache.iota.fey.performer.ZMQPublisher",
"parameters": {
"zmq_port": "5559",
"zmq_target": "192.168.0.139"
}
}
}
],
"connections": [
{
"Cherry": [
"ZMQPublisher"
]
}
]
}
]
}
Here is a very simple performer that operators on a schedule specified in an
orchestration and simple passes the string “Alive” to anything that it is
connected to i the orchestration that uses it.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.iota.fey.performer
import akka.actor.ActorRef
import org.apache.iota.fey.FeyGenericActor
import scala.collection.immutable.Map
import scala.concurrent.duration._
class Heartbeat(override val params: Map[String, String] = Map.empty,
override val backoff: FiniteDuration = 1.minutes,
override val connectTo: Map[String, ActorRef] = Map.empty,
override val schedulerTimeInterval: FiniteDuration = 30.seconds,
override val orchestrationName: String = "",
override val orchestrationID: String = "",
override val autoScale: Boolean = false) extends
FeyGenericActor {
override def onStart = {
}
override def onStop = {
}
override def onRestart(reason: Throwable) = {
// Called after actor is up and running - after self restart
}
override def customReceive: Receive = {
case x => log.info(s"Untreated $x")
}
override def processMessage[T](message: T, sender: ActorRef): Unit = {
}
override def execute() = {
propagateMessage("Alive")
}
}
> On Oct 31, 2016, at 9:32 PM, Dennis Jung <[email protected]> wrote:
>
> Hello Tony,
> Thanks for notification. Also, do you have a plan to make dev environment for
> Mac? It seems like it supports Linux only currently.
>
> BR,
> Dennis
>
> 2016-11-01 13:27 GMT+09:00 Tony Faustini <[email protected]
> <mailto:[email protected]>>:
> Hi Hadrian, It’s not on the Wiki yet - will put it there by tomorrow evening
> to give folks a chance to comment as requested by Justin. Yes the Wiki is
> quite slow tonight.
>
> Thanks
> -Tony
>
> > On Oct 31, 2016, at 9:24 PM, Hadrian Zbarcea <[email protected]
> > <mailto:[email protected]>> wrote:
> >
> > Looks good.
> >
> > I assume it's in the wiki, but cannot check, the wiki is incredibly slow
> > now.
> >
> > Hadrian
> >
> > On 11/01/2016 12:12 AM, Tony Faustini wrote:
> >> iota
> >>
> >> Open source system that enables the orchestration of IoT devices.
> >>
> >> iota has been incubating since 2016-01-20.
> >>
> >> Three most important issues to address in the move towards graduation:
> >>
> >> 1. Building the developer community
> >> 2. Outreach at events outside the Apache ecosystem to inform and invite
> >> participation in the project
> >> 3. Better leadership of the project itself
> >>
> >> Any issues that the Incubator PMC (IPMC) or ASF Board wish/need to be
> >> aware of?
> >>
> >> Committers are still very interested in seeing this podling develop.
> >>
> >> How has the community developed since the last report?
> >>
> >> Slowly - mainly 4 individuals that are contributing in spurts of activity.
> >> This needs to become consistent with better online leadership.
> >>
> >> How has the project developed since the last report?
> >>
> >> Technical contributions have been made and will continue to be made but
> >> there is a need engage and articulate the vision and architecture more
> >> actively on the mailing lists.
> >>
> >> Date of last release:
> >>
> >> Not released yet - had discussed an initial release at the end of this
> >> year but will need to see a stronger ecosystem develop to facilitate such
> >> a goal.
> >>
> >> When were the last committers or PMC members elected?
> >>
> >> 10 months ago
> >>
> >> Signed-off-by:
> >>
> >> [ ](iota) Daniel Gruno
> >> [ ](iota) Sterling Hughes
> >> [ ](iota) Justin Mclean
> >> [ ](iota) Hadrian Zbarcea
> >>
> >> Shepherd/Mentor notes:
> >>
> >>
>
>