Git Product home page Git Product logo

arcusplatform's Introduction

Arcus is an open-source home automation and control system, based on the Iris by Lowes codebase. This project contains the files necessary to run Arcus Platform, including the backend services and portions of the hub (agent).

Arcus Screenshot on Arcus Web Dashboard

Other Repositories

Arcus Platform does not contain a UI (beyond oculus, which is in Java). If you wish to access Arcus from a phone or web browser check out the other repositories under arcus-smart-home, these include:

  • arcusandroid - Android app for Arcus Platform
  • arcusios - iOS app for Arcus Platform
  • arcusweb - donejs web ui for Arcus Platform.
  • arcusipcd - IP Connected Device Protocol Implementation
  • arcushubos - Yocto Linux based HubOS Firmware

High Level Overview

Please see Overview for details. At present, local development is tricky to get setup and takes a considerable amount of time to configure. It is instead recommended that you setup Arcus in a container system, for example Kubernetes. See the community effort arcus-k8 for details.

Please see README.projects for details on the layout of this project. Individual subdirectories may have their own additional documentation.

Support

Please use http://forum.livingwithiris.com/forum/62-arcus/ for support and general questions.

arcusplatform's People

Contributors

andrewx192 avatar arcusadministrator avatar cottonaf avatar eanderso avatar msilvermanks avatar pcouto64 avatar pupper68k avatar thegillion avatar turnerd10 avatar type11 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arcusplatform's Issues

device-ota-firmware.download.host can't be set via environment variables

I don't see a clear way to set device-ota-firmware.download.host via an environment variable, since dashes are not supported and I don't see any logic in common/arcus-common/src/main/java/com/iris/bootstrap/Bootstrap.java to remap underscore to _ or otherwise.

I'll open a pull request to change this configuration directive to use dots instead of dashes, since that seems to be the usual scheme for configuration options.

Kafka does not start cleanly outside of runDocker

It is not possible to start the system with docker start because eyeris-kafka does not come up cleanly. This results in the following class of errors within all the other containers:

W0410 01:29:49.447 ucer-1 o.a.kafka.clients.NetworkClient] Error while fetching metadata with correlation id 3815 : {platform=LEADER_NOT_AVAILABLE}

The temporary solution is to blow away eyeris-kafka each time instead of reusing the container.

Exception thrown during removal of device

The drivers-service omits an exception when removing a device, which appears to be harmless:

W1013 20:26:31.713 read-5 c.google.common.cache.LocalCache] Exception thrown by removal listener
java.lang.ClassCastException: com.iris.messages.address.BroadcastAddress cannot be cast to com.iris.messages.address.DeviceProtocolAddress
	at com.iris.driver.platform.PlatformDriverExecutorRegistry.onExecutorEvicted(PlatformDriverExecutorRegistry.java:285)
	at com.iris.driver.platform.PlatformDriverExecutorRegistry$1.onRemoval(PlatformDriverExecutorRegistry.java:102)
	at com.google.common.cache.LocalCache.processPendingNotifications(LocalCache.java:1960)
	at com.google.common.cache.LocalCache$Segment.runUnlockedCleanup(LocalCache.java:3475)
	at com.google.common.cache.LocalCache$Segment.postWriteCleanup(LocalCache.java:3451)
	at com.google.common.cache.LocalCache$Segment.remove(LocalCache.java:3122)
	at com.google.common.cache.LocalCache.remove(LocalCache.java:4188)
	at com.google.common.cache.LocalCache$LocalManualCache.invalidate(LocalCache.java:4816)
	at com.iris.driver.platform.PlatformDriverExecutorRegistry.remove(PlatformDriverExecutorRegistry.java:269)
	at com.iris.driver.platform.PlatformDriverExecutorRegistry.doDelete(PlatformDriverExecutorRegistry.java:349)
	at com.iris.driver.platform.PlatformDriverExecutorRegistry.delete(PlatformDriverExecutorRegistry.java:255)
	at com.iris.driver.service.DeviceService.delete(DeviceService.java:317)
	at com.iris.driver.service.handler.RemoveRequestHandler.handleMessage(RemoveRequestHandler.java:88)
	at com.iris.core.platform.PlatformRequestDispatcher.handleRequest(PlatformRequestDispatcher.java:75)
	at com.iris.core.platform.PlatformRequestDispatcher.handleRequest(PlatformRequestDispatcher.java:36)
	at com.iris.core.platform.AbstractPlatformMessageHandler.lambda$handleRequestAndSendResponse$0(AbstractPlatformMessageHandler.java:42)
	at com.iris.core.platform.RequestResponseMessageBus.lambda$invokeAndSendIfNotNull$0(RequestResponseMessageBus.java:55)
	at com.iris.core.platform.RequestResponseMessageBus.invoke(RequestResponseMessageBus.java:62)
	at com.iris.core.platform.RequestResponseMessageBus.invokeAndSendIfNotNull(RequestResponseMessageBus.java:55)
	at com.iris.core.platform.AbstractPlatformMessageHandler.handleRequestAndSendResponse(AbstractPlatformMessageHandler.java:42)
	at com.iris.core.platform.AbstractPlatformMessageHandler.handleRequestAndSendResponse(AbstractPlatformMessageHandler.java:30)
	at com.iris.core.platform.AbstractMessageListener.handleMessage(AbstractMessageListener.java:147)
	at com.iris.core.platform.AbstractMessageListener.lambda$onMessage$0(AbstractMessageListener.java:139)
	at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:456)
	at com.iris.core.platform.AbstractMessageListener.onMessage(AbstractMessageListener.java:139)
	at com.iris.driver.platform.PlatformDriverService.handlePlatformMessage(PlatformDriverService.java:292)
	at com.iris.driver.platform.PlatformDriverService$DeliverMessageJob.run(PlatformDriverService.java:763)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at com.iris.util.MdcAwareRunnable.run(MdcAwareRunnable.java:60)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Upgrade gradle to 5.x

Gradle 5 is available, and keeping up to date with newer gradle versions will be important in supporting modern java versions (9+) in the future. Unfortunately this upgrade is non-trivial due to Gradle shipping with a newer version of groovy that can't easily be upgraded to, due to argument/validation issues when importing drivers and their capability files.

Could not find or load main class com.iris.driver.reflex.generator.ReflexGenerator

From ./gradlew startService

> Configure project :arcusplatform:tools
Building tools v2.1.0-SNAPSHOT
[ant:java] Error: Could not find or load main class com.iris.driver.reflex.generator.ReflexGenerator

> Task :platform:arcus-containers:driver-services:generateDriversReflexDB FAILED

FAILURE: Build failed with an exception.

* Where:
Build file '/home/wlnet/arcusplatform/platform/arcus-containers/driver-services/build.gradle' line: 112

* What went wrong:
Execution failed for task ':platform:arcus-containers:driver-services:generateDriversReflexDB'.
> Java returned: 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1m 1s
118 actionable tasks: 40 executed, 78 up-to-date

I've been using the following hack to get around this, with no observed effect:

$ git diff platform/arcus-containers/driver-services/build.gradle
diff --git a/platform/arcus-containers/driver-services/build.gradle b/platform/arcus-containers/driver-services/build.gradle
index ea089af..44274cf 100644
--- a/platform/arcus-containers/driver-services/build.gradle
+++ b/platform/arcus-containers/driver-services/build.gradle
@@ -109,7 +109,7 @@ task generateDriversReflexDB {
 
    doLast {
 
-      ant.java (fork:true, failonerror: true, classname: "com.iris.driver.reflex.generator.ReflexGenerator") {
+      ant.java (fork:true, failonerror: false, classname: "com.iris.driver.reflex.generator.ReflexGenerator") {
          arg(value: '--output')
          arg(value: 'none')
          arg(value: '--version')

Version numbers overlap for hubOS

It appears that IRIS used two different version numbers for hubOS updates (cc @pcouto64), which allowed for different updates to be targeted in firmware.xml. Unfortunately, this means that one needs to very careful to not create overlapping versions, lest they release an update which targets the wrong hub version. If this were to occur, it could potentially brick hubs.

Solution: in firmware.xml, add a hwver so that the version targets have to be scoped beyond (min existing, max existing) -> target. The hub will provide the hwver when connecting which will determine the firmware to upgrade in addition to min/max version

Subsystem Service fails to start

I'm unable to subsystem-service to start without modifying the code:

        at com.iris.bootstrap.Bootstrap.bootstrap(Bootstrap.java:241)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:146)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
        at com.iris.core.IrisApplication.main(IrisApplication.java:26)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for java.util.concurrent.ExecutorService annotated with @com.google.inject.name.Named(value=threadpool.incident) was bound.
  while locating java.util.concurrent.ExecutorService annotated with @com.google.inject.name.Named(value=threadpool.incident)
    for parameter 1 at com.iris.platform.subsystem.incident.AlarmIncidentServiceImpl.<init>(AlarmIncidentServiceImpl.java:55)
  at com.iris.platform.subsystem.incident.AlarmIncidentModule.configure(AlarmIncidentModule.java:44)

1 error
        at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:448)
        at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
        at com.google.inject.internal.InjectorImpl.createChildInjector(InjectorImpl.java:225)
        at com.netflix.governator.guice.LifecycleInjector.createChildInjector(LifecycleInjector.java:327)
        at com.netflix.governator.guice.LifecycleInjector.createInjector(LifecycleInjector.java:394)
        at com.netflix.governator.guice.LifecycleInjector.createInjector(LifecycleInjector.java:348)
        at com.iris.bootstrap.Bootstrap.bootstrap(Bootstrap.java:239)
        ... 3 more
E0410 05:55:20.472   main c.i.core.IrisAbstractApplication] Application failed to start
com.iris.bootstrap.BootstrapException: Error bootstrapping the injection context
        at com.iris.bootstrap.Bootstrap.bootstrap(Bootstrap.java:241)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:146)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
        at com.iris.core.IrisApplication.main(IrisApplication.java:26)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:

1) No implementation for java.util.concurrent.ExecutorService annotated with @com.google.inject.name.Named(value=threadpool.incident) was bound.
  while locating java.util.concurrent.ExecutorService annotated with @com.google.inject.name.Named(value=threadpool.incident)
    for parameter 1 at com.iris.platform.subsystem.incident.AlarmIncidentServiceImpl.<init>(AlarmIncidentServiceImpl.java:55)
  at com.iris.platform.subsystem.incident.AlarmIncidentModule.configure(AlarmIncidentModule.java:44)

1 error
        at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:448)
        at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
        at com.google.inject.internal.InjectorImpl.createChildInjector(InjectorImpl.java:225)
        at com.netflix.governator.guice.LifecycleInjector.createChildInjector(LifecycleInjector.java:327)
        at com.netflix.governator.guice.LifecycleInjector.createInjector(LifecycleInjector.java:394)
        at com.netflix.governator.guice.LifecycleInjector.createInjector(LifecycleInjector.java:348)
        at com.iris.bootstrap.Bootstrap.bootstrap(Bootstrap.java:239)
        ... 3 common frames omitted

> Task :platform:arcus-containers:subsystem-service:runDocker FAILED

FAILURE: Build failed with an exception.

to work around this change I made the following change:

$ git diff platform/arcus-containers/subsystem-service/src/main/java/com/iris/platform/subsystem/incident/AlarmIncidentServiceImpl.java
diff --git a/platform/arcus-containers/subsystem-service/src/main/java/com/iris/platform/subsystem/incident/AlarmIncidentServiceImpl.java b/platform/arcus-containers/subsystem-service/src/main/java/com/iris/platform/subsystem/incident/AlarmIncidentServiceImpl.java
index 7e88736..15eb40d 100644
--- a/platform/arcus-containers/subsystem-service/src/main/java/com/iris/platform/subsystem/incident/AlarmIncidentServiceImpl.java
+++ b/platform/arcus-containers/subsystem-service/src/main/java/com/iris/platform/subsystem/incident/AlarmIncidentServiceImpl.java
@@ -16,6 +16,7 @@
 package com.iris.platform.subsystem.incident;
 
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -43,7 +44,7 @@ public class AlarmIncidentServiceImpl extends AbstractPlatformService {
    @Inject
    public AlarmIncidentServiceImpl(
          PlatformMessageBus platformBus,
-         @Named(NAME_EXECUTOR_POOL) ExecutorService executor,
+         ForkJoinPool executor,
          SubsystemExecutorResolver subsystemExecutorResolver,
          PlatformDispatcherFactory dispatcherFactory,
          GetAttributesHandler getAttributesHandler,

How do I inject threadpool.incident?

Unable to start task runDocker

The task platform:arcus-modelmanager:runDocker fails to start because of a missing dependency from :arcus-khakis:startPlatform in :platform:arcus-modelmanager

$ ./gradlew rundocker

> Configure project :agent
agent version: 2.13.25-SNAPSHOT
agent dist version: iris-agent-hub-v2-2.13.25-SNAPSHOT

> Configure project :common
Building common v2.0.0

> Configure project :khakis
Building v2018.06.0-SNAPSHOT for docker: 2018.06.0

> Configure project :platform
Building with Iris Version 2.0.0-9bc8343
Building platform v2018.10.2

> Configure project :tools
Building tools v2.1.0-SNAPSHOT

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':platform:arcus-modelmanager:runDocker'.
> Task with path ':arcus-khakis:startPlatform' not found in project ':platform:arcus-modelmanager'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 0s

Rewrite agent SslKeyStore

The agent uses a custom PKCS1 key loader, which relies on deprecated classes in Java 8, including DerInputStream and DerValue:

   @SuppressWarnings("restriction")
   private static PrivateKey fromPkcs1(byte[] content) throws Exception {
      DerInputStream derReader = new DerInputStream(content);
      DerValue[] seq = derReader.getSequence(0);

      if (seq.length < 9) {
         throw new Exception("Could not parse a PKCS1 private key.");
      }

      BigInteger modulus = seq[1].getBigInteger();
      BigInteger publicExp = seq[2].getBigInteger();
      BigInteger privateExp = seq[3].getBigInteger();
      BigInteger prime1 = seq[4].getBigInteger();
      BigInteger prime2 = seq[5].getBigInteger();
      BigInteger exp1 = seq[6].getBigInteger();
      BigInteger exp2 = seq[7].getBigInteger();
      BigInteger crtCoef = seq[8].getBigInteger();

      RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
      KeyFactory factory = KeyFactory.getInstance("RSA");

      return factory.generatePrivate(keySpec);
   }

missing gzip compression support in platform-client

Client applications that use NettyIrisClient2 do not support gzip compressed payloads.
This causes the Android client to choke up on http 200 responses like so:

E/CORNEA: main BaseModelProvider Unable to load models
    com.iris.client.exception.ErrorResponseException: [http.error.200]: [Payload redacted before posting to github]

In the logs the payloads turn out as unrenderable garbled nonsense text.

Poor story around cryptography

Today Arcus uses multiple cryptographic functions to encrypt and decrypt data, all which have limitations.

  • com.iris.security.crypto.AES uses AES in CBC mode with a fixed IV.
  • com.iris.Utils provides another AES CBC implementation with a random IV, however it isn't used everywhere, doesn't have unit tests, and still doesn't provide any form of authenticated encryption.

These should be replaced by some form of AEAD, e.g. AES-GCM. Utils seems like a bit of a dumping place, so this should probably go in com.iris.security.crypto.AES and com.iris.Utils should be retired for cryptographic purposes.

Finally - regardless of the cipher that's used, it will be important to support re-keying and algorithm changes in the future. There should likely be an online and offline job to facilitate changes in the future.

Allow reflexes to have history

Reflexes appear to be based on the hub reporting device's current state to the platform, which means that any offline activity is missed. Look into and see if these can be converted to more of a history.

personal information in debug messages

NettyIrisClient2 displays decoded traffic in the logs, which includes email addresses, phone numbers, physical addresses, and more.

There should be some redaction of what is being logged.

Platform Client does not support TLS SNI

The arcus platform client (used by oculus and the android app) does not support TLS SNI. This is challenging in a world where IP addresses are not dedicated to specific servers.

Unit test fails when DST ends

Some failures:

Class com.iris.common.rule.trigger.TestTimeOfDayTrigger:

	at org.junit.Assert.fail(Assert.java:88)
	at org.junit.Assert.failNotEquals(Assert.java:743)
	at org.junit.Assert.assertEquals(Assert.java:519)
	at org.junit.Assert.assertEquals(Assert.java:609)
	at com.iris.common.rule.trigger.TestTimeOfDayTrigger.testTriggersLaterToday(TestTimeOfDayTrigger.java:73)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.lang.Thread.run(Thread.java:748)
java.lang.AssertionError: expected:<1.57280043E12> but was:<1.57279676E12>
	at org.junit.Assert.fail(Assert.java:88)
	at org.junit.Assert.failNotEquals(Assert.java:743)
	at org.junit.Assert.assertEquals(Assert.java:519)
	at org.junit.Assert.assertEquals(Assert.java:609)
	at com.iris.common.rule.trigger.TestTimeOfDayTrigger.testTriggersTommorrow(TestTimeOfDayTrigger.java:94)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:118)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.lang.Thread.run(Thread.java:748)```

arcus-modelmanager support-resources missing

It appears that there's a dependency on support-resources existing, but it wasn't released as part of arcus. Probably need to remove this dependency

11:22:20.959 [main] INFO  c.iris.core.IrisAbstractApplication - starting configured application:
        arcus-modelmanager v2018.10.2 [application directory: /home/wlnet/arcusplatform/platform/arcus-modelmanager/build/install/modelmanager]
Home directory not found @ /home/wlnet/arcusplatform/platform/arcus-modelmanager/src/dist/support-resources

java.lang.IllegalArgumentException: Home directory not found @ /home/wlnet/arcusplatform/platform/arcus-modelmanager/src/dist/support-resources
        at com.iris.modelmanager.context.ManagerContext$Builder.validateHomeDirectory(ManagerContext.java:96)
        at com.iris.modelmanager.context.ManagerContext$Builder.build(ManagerContext.java:77)
        at com.iris.modelmanager.ModelManager.createContext(ModelManager.java:51)
        at com.iris.modelmanager.ModelManager.start(ModelManager.java:41)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:181)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
        at com.iris.modelmanager.ModelManager.main(ModelManager.java:46)
11:22:20.961 [main] ERROR c.iris.core.IrisAbstractApplication - Application failed to start
java.lang.IllegalArgumentException: Home directory not found @ /home/wlnet/arcusplatform/platform/arcus-modelmanager/src/dist/support-resources
        at com.iris.modelmanager.context.ManagerContext$Builder.validateHomeDirectory(ManagerContext.java:96)
        at com.iris.modelmanager.context.ManagerContext$Builder.build(ManagerContext.java:77)
        at com.iris.modelmanager.ModelManager.createContext(ModelManager.java:51)
        at com.iris.modelmanager.ModelManager.start(ModelManager.java:41)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:181)
        at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
        at com.iris.modelmanager.ModelManager.main(ModelManager.java:46)
Shutting down...
11:22:20.962 [Thread-1] INFO  com.iris.bootstrap.ServiceLocator - Received shutdown signal, shutting down modules
11:22:20.963 [Thread-1] INFO  c.i.c.m.r.IrisMetricsTopicReporter - Stopping topics reporter
11:22:21.041 [Thread-1] INFO  o.a.k.clients.producer.KafkaProducer - Closing the Kafka producer with timeoutMillis = 9223372036854775807 ms.
11:22:53.314 [Thread-1] INFO  com.iris.bootstrap.ServiceLocator - Shutdown

> Task :platform:arcus-modelmanager:run-support FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':platform:arcus-modelmanager:run-support'.
> Process 'command '/usr/lib/jvm/java-8-openjdk-amd64/bin/java'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1m 56s
70 actionable tasks: 16 executed, 54 up-to-date

Cannot SSH into v3 Hub

Built the dongle per instructions with my hub's .dbg file on a FAT32 thumb drive. Logged in with root username and the v3 password. Access denied.

Remove nest suppport

The code for the nest thermostat doesn't appear to have been included, but it's still required to be setup in the configuration. Remove it until someone has time to add it back.

Adjust defaults for easier setup

Currently the setup process is complicated by needing to setup the configuration for each service and detail (e.g. billing api credentials) in order to get the platform up. Since there will be more deployments of Arcus, the defaults should be changed so that reasonable defaults (e.g. billing is disabled) are in place, similar to how other settings (like CORS) are handled.

Error: Could not find or load main class com.iris.capability.generator.java.Generator

I get this error when trying to build the repo:

D:\Files\arcusplatform>gradlew build

> Configure project :agent
agent version: 2.13.25-SNAPSHOT
agent dist version: iris-agent-hub-v2-2.13.25-SNAPSHOT

> Configure project :common
Building common v2.0.0

> Configure project :khakis
Building v2018.06.0-SNAPSHOT for docker: 2018.06.0

> Configure project :platform
Building with Iris Version 2.0.0-9bc8343
Building platform v2018.10.2

> Configure project :tools
Building tools v2.1.0-SNAPSHOT

> Task :common:arcus-model:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning

> Task :common:arcus-client:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning

> Task :common:arcus-metrics:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning

> Task :common:arcus-common:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning

> Task :common:arcus-protoc:compileGroovy
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning

> Task :common:arcus-protoc-runtime:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning

> Task :common:arcus-model:capability-generator:compileJava
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning

> Task :common:arcus-protocol:generateSource FAILED
Generating templates from protocol...
Error: Could not find or load main class com.iris.capability.generator.java.Generator

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':common:arcus-protocol:generateSource'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_191\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 13s
17 actionable tasks: 17 executed

Here's the stacktrace:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':common:arcus-protocol:generateSource'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
        at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46)
        at org.gradle.execution.taskgraph.LocalTaskInfoExecutor.execute(LocalTaskInfoExecutor.java:42)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:277)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:262)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:135)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.execute(DefaultTaskPlanExecutor.java:200)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.executeWithWork(DefaultTaskPlanExecutor.java:191)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.run(DefaultTaskPlanExecutor.java:130)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_191\bin\java.exe'' finished with non-zero exit value 1
        at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:395)
        at org.gradle.process.internal.DefaultJavaExecAction.execute(DefaultJavaExecAction.java:37)
        at org.gradle.api.tasks.JavaExec.exec(JavaExec.java:79)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:801)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:768)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:131)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:120)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:99)
        ... 31 more

Hub authenticator is noauth

I've noticed in a couple of places that the client-bridge authenticator is stubbed out to be noauth

bind(Authenticator.class).to(NoopAuthenticator.class);

this exists for ipcd-bridge and hub-bridge - where mutual TLS authentication should be possible. Based on my research thus far, for hub-bridge we should only need to implement client certificate verification against the hub id based on the mac address in the certificate. I haven't looked into ipcd yet, but I assume it will be use case specific, unless the protocol can be amended to do some sort of certificate pinning (e.g. the first certificate seen for a device is the accepted one, and there's no relation to the serial number or otherwise device id)

Null Execption with Model Manager History

When running start up getting the following error in model manager module. In previous changes services was commented out.

   arcus-modelmanager v2018.10.2 [application directory: /home/jsb145/arcusplatform/platform/arcus-modelmanager/build/install/modelmanager]

null

java.lang.NullPointerException
at com.iris.modelmanager.engine.ExecutionEngine.createSession(ExecutionEngine.java:193)
at com.iris.modelmanager.engine.ExecutionEngine.(ExecutionEngine.java:54)
at com.iris.modelmanager.ModelManager.start(ModelManager.java:41)
at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:181)
at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
at com.iris.modelmanager.ModelManager.main(ModelManager.java:46)
07:33:01.304 [main] ERROR c.iris.core.IrisAbstractApplication - Application failed to start
java.lang.NullPointerException: null
at com.iris.modelmanager.engine.ExecutionEngine.createSession(ExecutionEngine.java:193)
at com.iris.modelmanager.engine.ExecutionEngine.(ExecutionEngine.java:54)
at com.iris.modelmanager.ModelManager.start(ModelManager.java:41)
at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:181)
at com.iris.core.IrisAbstractApplication.exec(IrisAbstractApplication.java:125)
at com.iris.modelmanager.ModelManager.main(ModelManager.java:46)
Shutting down...
07:33:01.307 [Thread-1] INFO com.iris.bootstrap.ServiceLocator - Received shutdown signal, shutting down modules
07:33:01.307 [Thread-1] INFO com.iris.bootstrap.ServiceLocator - Shutdown

Task :platform:arcus-modelmanager:run-history FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':platform:arcus-modelmanager:run-history'.

Process 'command '/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/bin/java'' finished with non-zero exit value 1

Kafka host is hard coded

kafka.eyeris or kafkaops.eyeris is hard coded several places, making use in Google Cloud more difficult:

arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaAnalyticsConfig.java:	protected String getDefaultBootstrapServers() {
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaAnalyticsConfig.java-		return "kafka.eyeris:9092";
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaAnalyticsConfig.java-	}
--
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaConfig.java:   protected String getDefaultBootstrapServers() {
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaConfig.java-      return "kafka.eyeris:9092";
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaConfig.java-   }
--
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaOpsConfig.java:   protected String getDefaultBootstrapServers() {
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaOpsConfig.java-      return "kafkaops.eyeris:9092";
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/KafkaOpsConfig.java-   }
--
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java:         this.bootstrapServers = getDefaultBootstrapServers();
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java-      }
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java-      if (isTransientOffsets() && !Boolean.FALSE.equals(getEnableAutoCommit())) {
--
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java:   protected abstract String getDefaultBootstrapServers();
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java-   protected abstract String getDefaultSerializer();
arcusplatform/platform/arcus-lib/src/main/java/com/iris/core/messaging/kafka/AbstractKafkaConfig.java-   protected abstract String getDefaultKeySerializer();

Upgrade Kafka Consumer

The kafka client is currently version 0.10.0.0, and many aspects of the API have been changed since this version, making the upgrade non-trivial

Could not find or load main class com.iris.bridge.server.BridgeServer

I cloned the github repository to my hard drive. I am working in the latest Eclipse IDE and am attempting to Run the arcusplatform project.

I get the following error:

Error: Could not find or load main class com.iris.bridge.server.BridgeServer
Picked up JAVA_TOOL_OPTIONS: -agentpath:"c:\windows\fireeye\javaagentdll_00.dll"

Has anyone else run into this issue?

Productionized setup instructions

I've already gotten arcusplatform to run using gradle, e.g. in docker, but I'm unsure if this is how it was intended to run in production, as the processes within the container run as root and otherwise generally doesn't appear to be production ready (see #11 and #12 as potential examples)

techdebt: use of APNs binary format

While setting up push notifications for the iOS application, I noticed that pushy (the library, not the service) is using a version from 2015 which pre-dates Apple's transition to HTTP/2. I'm not sure how much longer this will be supported but it seems like the new HTTP/2 format is easier to work with and the path forward. We should upgrade the pushy library and switch to HTTP/2.

Hold my hand please..

Ok umm.. I have no idea how all this works.. I know, I know... how annoying, but I have this insatiable hobby of smart homing and I have all this iris stuff and it appears as if you guys are trying to rebuild a more workable platform for the iris products people spent their hard earned money on. But can somebody please please please just post how to begin.. how do I get this code onto the hub? You know, the iris hub... right? Do I connect the hub by usb to my computer and just run the code? Or does it do it wirelessly (probably not, right?).. and do I do it only through terminal from my Mac? Or is there a program like Code Runner that can do it so much easier? Am I supposed to be entering code in terminal to customize only the parts I need or is there a file I run and BAM it’s all good?

Default user to premium tier

For the open source version of Arcus, there's little value in putting users in the "BASIC" tier to start - they should have all functionality from the start.

Agent 'run' target depdencies missing (can't build agent)

I'm trying to build the code to run on the agent, but one of the dependencies, run-hub-v2 is missing:


> Configure project :agent
agent version: 2.13.25-SNAPSHOT
agent dist version: iris-agent-hub-v2-2.13.25-SNAPSHOT

> Configure project :common
Building common v2.0.0

> Configure project :khakis
Building v2018.06.0-SNAPSHOT for docker: 2018.06.0

> Configure project :platform
Building with Iris Version 2.0.0-9bc8343
Building platform v2018.10.2

> Configure project :tools
Building tools v2.1.0-SNAPSHOT

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':agent:arcus-hal:arcus-hal-hub-v2:run'.
> Task with path 'run-hub-v2' not found in project ':agent:arcus-hal:arcus-hal-hub-v2'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1s

Update older hubs?

I got another hub for testing purposes, but I'm unsure how to update it now that the iris servers are gone. The hubdebug tools mention providing a firmware image, but that appears to be unavailable now.

Add support for tamper information

Many of the devices support providing tamper information, but there's no capability for it internally. We should:

  • Add capability for tamper information (+ any relevant tests)
  • Adjust platform messages if needed to provide information about tamper to the user
  • Implement tamper support for at least one device (maybe a contact sensor?)

Documentation

Need an architecture diagram (what talks to what etc) and simple document on deploying this whole setup. Thanks.

ppa:wedupd8team/java is discontinued

With the new Oracle Java license put into effect on April 16, 2019, the webupd8team/java PPA has been discontinued and no longer works. This is significant as the :platform:arcus-khakis:distDocker Gradle task relies on this to complete. Maybe try switching to the openjdk-8-jdk package instead?

Write driver for SmartThings Button

Add support for the SmartThings button, which also appears to have temperature reporting. Some information about the device:

D0923 04:27:05.799 e-6122              driver._ZB_Fallback] Starting driver [DriverId [name=_ZB_Fallback, version=Version [1.0]]]
D0923 04:27:05.799 e-6122              driver._ZB_Fallback] Driver [DriverId [name=_ZB_Fallback, version=Version [1.0]]] upgraded
W0923 04:27:05.799 e-6122 c.i.d.s.i.DefaultNameInitializer] No product: [null] found for population: [general] falling back to defaultName
D0923 04:27:05.808 e-6122 c.i.d.s.i.DefaultNameInitializer] Setting device name to New Device 2
D0923 04:27:05.808 e-6122              driver._ZB_Fallback] Zigbee Fallback Driver started.
D0923 04:27:05.810 e-6122              driver._ZB_Fallback] Attributes: {ZIGB:dcap=0, ZIGB:profiles=[{hubzbprofile:endpoints=[{hubzbendpoint:devver=0, hubzbendpoint:datecode=null, hubzbendpoint:pwr=3, hubzbendpoint:appver=17, hubzbendpoint:id=1, hubzbendpoint:manuf=Samjin, hubzbendpoint:zclver=-1, hubzbendpoint:ccls=[{hubzbcluster:id=3, hubzbcluster:server=false}, {hubzbcluster:id=25, hubzbcluster:server=false}], hubzbendpoint:hwver=0, hubzbendpoint:model=button, hubzbendpoint:stkver=-1, hubzbendpoint:devid=1026, hubzbendpoint:scls=[{hubzbcluster:id=0, hubzbcluster:server=true}, {hubzbcluster:id=32, hubzbcluster:server=true}, {hubzbcluster:id=1280, hubzbcluster:server=true}, {hubzbcluster:id=1, hubzbcluster:server=true}, {hubzbcluster:id=1026, hubzbcluster:server=true}, {hubzbcluster:id=3, hubzbcluster:server=true}, {hubzbcluster:id=2821, hubzbcluster:server=true}]}], hubzbprofile:id=260}], ZIGB:maxots=82, ZIGB:nwk=42721, ZIGB:eui64=2913150560251691217, ZIGB:maxbuf=82, ZIGB:pdesc=49424, ZIGB:nflags=16386, ZIGB:manufacturer=4673, ZIGB:model=button, ZIGB:smask=11264, ZIGB:maxits=82, ZIGB:vendor=Samjin, ZIGB:hub={eui64=3781220577624460}, ZIGB:mcap=128}
D0923 04:27:05.814 e-6122    c.i.c.m.kafka.KafkaMessageBus] Sending message [PlatformMessage [value=MessageBody [messageType=base:Added, attributes={base:caps=[dev, devadv, devconn, base], devadv:errors={pairing.failed=Driver could not be determined.}, devadv:driverversion=1.0, base:instances={}, devadv:drivername=_ZB_Fallback, dev:place=8f955ff0-ce66-4e82-a7ce-88f8727c0c96, base:id=2f2ed61c-527e-4c8a-a78a-e6981279fe0f, base:address=DRIV:dev:2f2ed61c-527e-4c8a-a78a-e6981279fe0f, dev:vendor=Unknown, base:tags=[], base:type=dev, devadv:protocol=ZIGB, devadv:degraded=false, base:images={}, devadv:protocolid=0UAIAQCXbSgAAAAAAAAAAAAAAAA=, devadv:degradedCode=none, dev:account=8feeeb4e-cd54-4860-9bde-9feb989332e8, dev:model=Unknown, dev:name=New Device 2, devadv:driverstate=unsupported, devadv:driverhash=LVuawU38Zc0XFVOuVaO74gcodw8, devadv:hubLocal=false, dev:devtypehint=dev, devadv:added=Mon Sep 23 04:27:05 UTC 2019}], [Message [source=DRIV:dev:2f2ed61c-527e-4c8a-a78a-e6981279fe0f,type=base:Added]]]]```

Can't customize devices when pairing

When pairing, the user is prompted to configure any paired devices. This will unfortunately fail due to the following error:

D0501 03:56:53.944 p-1799  com.iris.messages.errors.Errors] Translating exception
java.lang.IllegalArgumentException: Could not load type [interface com.iris.platform.subsystem.SubsystemDao]: Could not load type [interface com.iris.platform.subsystem.SubsystemDao]: Guice configuration errors:

1) No implementation for com.iris.platform.subsystem.SubsystemDao was bound.
  while locating com.iris.platform.subsystem.SubsystemDao

1 error
	at com.iris.bootstrap.ServiceLocator.getInstance(ServiceLocator.java:80)
	at com.iris.platform.pairing.customization.SecurityModeCustomization.apply(SecurityModeCustomization.java:60)
	at com.iris.platform.pairing.customization.PairingCustomization.toStepIf(PairingCustomization.java:136)
	at com.iris.platform.pairing.customization.PairingCustomizationManager.lambda$apply$0(PairingCustomizationManager.java:101)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.iris.platform.pairing.customization.PairingCustomizationManager.apply(PairingCustomizationManager.java:103)
	at com.iris.platform.pairing.handler.CustomizeRequestHandler.customize(CustomizeRequestHandler.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.iris.reflection.MethodInvoker.apply(MethodInvoker.java:59)
	at com.iris.core.platform.RequestResponseMessageBus.invoke(RequestResponseMessageBus.java:73)
	at com.iris.core.platform.RequestResponseMessageBus.invokeAndSendResponse(RequestResponseMessageBus.java:43)
	at com.iris.core.platform.PlatformDispatcher.handleRequest(PlatformDispatcher.java:81)
	at com.iris.core.platform.PlatformDispatcher.onMessage(PlatformDispatcher.java:74)
	at com.iris.core.platform.PlatformDispatcher.onMessage(PlatformDispatcher.java:36)
	at com.iris.executor.PlaceExecutor.lambda$null$0(PlaceExecutor.java:96)
	at com.iris.executor.TaskQueue$RunnableFuture.run(TaskQueue.java:200)
	at com.iris.executor.TaskQueue.dispatch(TaskQueue.java:129)
	at com.iris.util.MdcAwareRunnable.run(MdcAwareRunnable.java:60)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Could not load type [interface com.iris.platform.subsystem.SubsystemDao]: Guice configuration errors:

1) No implementation for com.iris.platform.subsystem.SubsystemDao was bound.
  while locating com.iris.platform.subsystem.SubsystemDao

1 error
	at com.iris.bootstrap.guice.GuiceServiceLocator.getInstance(GuiceServiceLocator.java:81)
	at com.iris.bootstrap.ServiceLocator.getInstance(ServiceLocator.java:78)
	... 29 common frames omitted
Caused by: com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for com.iris.platform.subsystem.SubsystemDao was bound.
  while locating com.iris.platform.subsystem.SubsystemDao

1 error
	at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1035)
	at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:994)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1044)
	at com.iris.bootstrap.guice.GuiceServiceLocator.getInstance(GuiceServiceLocator.java:79)
	... 30 common frames omitted
D0501 03:56:53.944 p-1799    c.i.c.m.kafka.KafkaMessageBus] Sending message [PlatformMessage [value=ErrorEvent [code=IllegalArgumentException, message=Could not load type [interface com.iris.platform.subsystem.SubsystemDao]: Could not load type [interface com.iris.platform.subsystem.SubsystemDao]: Guice configuration errors:

1) No implementation for com.iris.platform.subsystem.SubsystemDao was bound.
  while locating com.iris.platform.subsystem.SubsystemDao

The following fix fixes this

$ git diff platform/arcus-lib/src/main/java/com/iris/platform/pairing/customization/SecurityModeCustomization.java
diff --git a/platform/arcus-lib/src/main/java/com/iris/platform/pairing/customization/SecurityModeCustomization.java b/platform/arcus-lib/src/main/java/com/iris/platform/pairing/customization/SecurityModeCustomization.java
index bcab9e2..75cd456 100644
--- a/platform/arcus-lib/src/main/java/com/iris/platform/pairing/customization/SecurityModeCustomization.java
+++ b/platform/arcus-lib/src/main/java/com/iris/platform/pairing/customization/SecurityModeCustomization.java
@@ -27,6 +27,7 @@ import com.iris.messages.model.Place;
 import com.iris.messages.model.serv.AlarmModel;
 import com.iris.platform.model.ModelEntity;
 import com.iris.platform.subsystem.SubsystemDao;
+import com.iris.platform.subsystem.cassandra.CassandraSubsystemDao;
 
 class SecurityModeCustomization extends PairingCustomization {
        
@@ -57,7 +58,7 @@ class SecurityModeCustomization extends PairingCustomization {
                // FIXME inject the subsystem dao
                ModelEntity entity =
                                ServiceLocator
-                                       .getInstance(SubsystemDao.class)
+                                       .getInstance(CassandraSubsystemDao.class) //CassandraSubsystemDao.class
                                        .findByPlaceAndNamespace(place.getId(), AlarmSubsystemCapability.NAMESPACE);
                return AlarmModel.getDevices(AlarmSubsystemCapability.ACTIVEALERTS_SECURITY, entity, ImmutableSet.of()).contains(device.getAddress().getRepresentation());
        }

Remove apptentive

client-bridge requires apptentive to be configured, but as far as I can tell, the configuration isn't used because that code isn't included. This issue tracks removing the configuration options so that they don't have to be setup

Add support for schedules that only happen when someone is home

There doesn't seem to be a good way to have an appliance turn on at a certain time if someone is home / the alarm is unlocked, or if a specific person is present. It would be nice to add this to the scheduling system, or add the ability to create a rule that fires at a given time if someone is home.

Potentially explore adding this to scheduler-service or rule-service. I looked into the latter in the past, but struggled because rules can't fire at a user controlled time.

Tests fail due to sourceCompatibility 7/8 mix

After integration of all the various pull requests today, it appears that there's an minor conflict between upgrading the sourceCompatibility in one project and gradle 5.x

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':tools:arcus-captools:test'.
> Could not resolve all task dependencies for configuration ':tools:arcus-captools:testRuntimeClasspath'.
   > Could not resolve project :common:arcus-model.
     Required by:
         project :tools:arcus-captools
      > Unable to find a matching variant of project :common:arcus-model:
          - Variant 'apiElements' capability com.iris:arcus-model:unspecified:
              - Incompatible attributes:
                  - Required org.gradle.jvm.version '7' and found incompatible value '8'.
                  - Required org.gradle.usage 'java-runtime' and found incompatible value 'java-api'.
              - Other attributes:
                  - Found org.gradle.category 'library' but wasn't required.
                  - Required org.gradle.dependency.bundling 'external' and found compatible value 'external'.
                  - Required org.gradle.libraryelements 'jar' and found compatible value 'jar'.
          - Variant 'runtimeElements' capability com.iris:arcus-model:unspecified:
              - Incompatible attribute:
                  - Required org.gradle.jvm.version '7' and found incompatible value '8'.
              - Other attributes:
                  - Found org.gradle.category 'library' but wasn't required.
                  - Required org.gradle.dependency.bundling 'external' and found compatible value 'external'.
                  - Required org.gradle.libraryelements 'jar' and found compatible value 'jar'.
                  - Required org.gradle.usage 'java-runtime' and found compatible value 'java-runtime'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.6.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 5s

we should be able to bump everything to java 8 (since we aren't supporting old java 1.7 hubs anymore)

Oculus fails to load configuration, throws NullPointerException instead of showing login screen

Expected behavior: ./gradlew :tools:oculus:run results in Oculus opening.
Actual behavior: program opens, shows "loading configuration" and disappears.

Full exception stack:

> Task :tools:oculus:run
22:20:49.844 [main] WARN  c.n.g.lifecycle.ClasspathScanner - No base packages specified - no classpath scanning will be done
22:20:51.882 [main] WARN  com.iris.oculus.Main - Uncaught Exception
java.lang.reflect.InvocationTargetException: null
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:1349)
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:1324)
        at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1353)
        at com.iris.oculus.Main.main(Main.java:267)
Caused by: java.lang.NullPointerException: null
        at com.iris.oculus.modules.session.SessionController.getLastSession(SessionController.java:630)
        at com.iris.oculus.modules.session.SessionController.login(SessionController.java:254)
        at com.iris.oculus.Main.lambda$main$7(Main.java:304)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
        at java.awt.EventQueue.access$500(EventQueue.java:97)
        at java.awt.EventQueue$3.run(EventQueue.java:709)
        at java.awt.EventQueue$3.run(EventQueue.java:703)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
22:20:51.882 [main] WARN  com.iris.oculus.Application - Uncaught Exception
java.lang.reflect.InvocationTargetException: null
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:1349)
        at java.awt.EventQueue.invokeAndWait(EventQueue.java:1324)
        at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1353)
        at com.iris.oculus.Main.main(Main.java:267)
Caused by: java.lang.NullPointerException: null
        at com.iris.oculus.modules.session.SessionController.getLastSession(SessionController.java:630)
        at com.iris.oculus.modules.session.SessionController.login(SessionController.java:254)
        at com.iris.oculus.Main.lambda$main$7(Main.java:304)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
        at java.awt.EventQueue.access$500(EventQueue.java:97)
        at java.awt.EventQueue$3.run(EventQueue.java:709)
        at java.awt.EventQueue$3.run(EventQueue.java:703)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
<============-> 99% EXECUTING [12s]

This can be fixed by a simple null check in tools/oculus/src/main/java/com/iris/oculus/modules/session/SessionController.java

Watch dog running

When SSH into the hub the Watchdog with reboot the hub on a time out. I am trying to kill the watchdog but can't I will report back if I find out more.

Write generic IPCD Drivers

Rather than requiring every device to be supported in IPCD, generic drivers could be created to support easy addition of new devices (e.g. without writing new IPCD drivers). Write some generic drivers for:

  • Switch
  • DimmerSwitch
  • Contact Sensor
  • Motion Sensor
  • Smoke Alarm
  • Siren

These will allow a lot more functionality to be added in the future, without having to tinker with ArcusPlatform or add a bunch of custom code (like what was done for the existing IPCD integrations).

Once this is completed, any user should be able to create their own devices based on these drivers near-trivially in a programming language like Python, without touching the code in Arcus Platform.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.