diff --git a/alarm-generator/README.md b/alarm-generator/README.md
new file mode 100644
index 0000000..fec04e4
--- /dev/null
+++ b/alarm-generator/README.md
@@ -0,0 +1,43 @@
+## Automatic Alarm Generator
+
+Alarm-generator is a process that sends a stream of simulate_alarm requests to Voltha. The rate at which the alarms are generated and the duration between alarm RAISE and alarm CLEAR can be configured using command line options. 
+
+### Requirements
+
+Voltha must be installed. A useful environment with the appropriate libraries already installed is the Voltha vcli container. This container can typically be entered using kubectl (for example, `kubectl -n voltha exec -it <vcli-container-name> bash`.
+
+TODO: Eventually alarm-generator may be installed into its own container, deployable with helm. 
+
+### Usage
+
+The following command-line arguments are supported:
+
+* **-C CONSUL, --consul CONSUL**. Specifies the hostname and port of the consul agent. *(default: localhost:8500)*
+* **-L, --lookup**. Lookup Voltha endpoints based on service entries (see also the -C option)
+* **-G, --global_requests**. All requests to the Voltha gRPC service are global.
+* **-g GRPC_ENDPOINT, --grpc-endpoint GRPC_ENDPOINT**. \<hostname\>:\<port\> of Voltha gRPC service. *(default=localhost:50055)*
+* **-d DEVICE_ID, --device_id DEVICE_ID**. Device id of the OLT device that simulated alarms will be sent for. If no device id is specified, then Voltha will be queried and the first available OLT device id will be used.
+* **-o ONU_ID, --one_id ONU_ID**. Device id of the ONU to send in simulated alarms. If not specified, then Voltha will be queried, and all available ONUs attached to the OLT will be used.
+* **-i INTF_ID, --intf_id INTF_ID**. Interface id to send in simulated alarms. If ONU_ID is unspecified (see -o option), then Voltha will be queried for the interface id, and this setting will be ignored.
+* **-r RATE, --rate RATE**. Rate in alarms/second to generate. Fractional values are permitted. *(default: 0.1)*
+* **-u DURATION, --duration DURATION**. Duration in seconds between alarm RAISE and alarm CLEAR. *(default: 1)*
+
+### OLT and ONU information used in alarms 
+
+Each simulated alarm typically has three arguments, an OLT device id, an ONU device id, and an interface id. These options may be configured from the command line (-d, -o, and -i), or they may be learned from Voltha if these three options are unspecified.
+
+Specifying these options from the command line may be handy in those cases where an OLT is simulated rather than being physically present.
+
+### Example usage
+
+Generate 1 request per second, each request a duration of 2 seconds. Learn OLT and ONU information by querying Voltha:
+
+    main.py -C consul:8500 -g voltha:50555 -G -r 1 -u 2
+
+Generate 1 request per second, each request a duration of 2 seconds. For OLT id, use the first OLT found in Voltha. Use the onu_device_id 00012bc90d6552dd and the intf_id 0:
+
+    main.py -C consul:8500 -g voltha:50555 -G -r 1 -u 2 -i 0 -o 00012bc90d6552dd
+
+Generate 1 request every ten seconds, each request a duration of 4 seconds. OLT id,one_device_id, and intf_id are all configured from the command-line:
+
+    main.py -C consul:8500 -g voltha:50555 -G -r 0.1 -u 4 -i 0 -o 00012bc90d6552dd -d 00012bc90d6552dd
diff --git a/alarm-generator/main.py b/alarm-generator/main.py
new file mode 100644
index 0000000..ce0f703
--- /dev/null
+++ b/alarm-generator/main.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed 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.
+
+"""
+Alarm-generator is a process that sends a stream of simulate_alarm requrests to VOLTHA. It will automatically pick
+between a variety of ONU-related alarms. The number of alarms per second is configurable (for example, 0.01 = one
+alarm per hundred seconds), and the duration of the alarm from RAISE to CLEAR is also configurable.
+
+By default, if not device is specified, then VOLTHA will be queried for the first device.
+
+Example:
+    # Generate 1 request per second, each request a duration of 2 seconds. Use whatever OLT device id exists in
+    # VOLTHA. Use intf_id =1234 and onu_device_id=5678
+    main.py -C consul:8500 -g voltha:50555 -G -r 1 -u 2 -i 1234 -o 5678
+
+    # Generate 1 request per second, each request a duration of 2 seconds. Use whatever OLT and ONUs exist in
+    # VOLTHA.
+    main.py -C consul:8500 -g voltha:50555 -G -r 1 -u 2
+
+"""
+import argparse
+import copy
+import functools
+import os
+import random
+import structlog
+import sys
+import time
+from threading import Timer
+
+import grpc
+from consul import Consul
+from simplejson import dumps
+
+from google.protobuf.empty_pb2 import Empty
+from voltha.protos import third_party
+from voltha.protos import voltha_pb2, common_pb2
+
+defs = dict(
+    # config=os.environ.get('CONFIG', './cli.yml'),
+    consul=os.environ.get('CONSUL', 'localhost:8500'),
+    voltha_grpc_endpoint=os.environ.get('VOLTHA_GRPC_ENDPOINT',
+                                        'localhost:50055'),
+    global_request=os.environ.get('GLOBAL_REQUEST', False),
+    device_id = None,
+    intf_id = "1234",
+    onu_id = None,
+    rate = 0.1,
+    duration = 1,
+)
+
+def enum2name(msg_obj, enum_type, enum_value):
+    descriptor = msg_obj.DESCRIPTOR.enum_types_by_name[enum_type]
+    name = descriptor.values_by_number[enum_value].name
+    return name
+
+banner = """\
+         _ _   _          
+__ _____| | |_| |_  __ _   
+\ V / _ \ |  _| ' \/ _` | Alarm Generator
+ \_/\___/_|\__|_||_\__,_|  
+"""
+
+class VOLTHAClient(object):
+    def __init__(self, voltha_grpc, global_request=False):
+        self.voltha_grpc = voltha_grpc
+        self.global_request = global_request
+        self.channel = None
+        self.stub = None
+        self.log = structlog.get_logger()
+        self.stdout = sys.stdout
+
+    def get_channel(self):
+        if self.channel is None:
+            self.channel = grpc.insecure_channel(self.voltha_grpc)
+        return self.channel
+
+    def get_stub(self):
+        if self.stub is None:
+            self.stub = \
+                voltha_pb2.VolthaGlobalServiceStub(self.get_channel()) \
+                    if self.global_request else \
+                    voltha_pb2.VolthaLocalServiceStub(self.get_channel())
+        return self.stub
+
+    def get_first_olt_device_id(self):
+        """ Query VOLTHA and pick some olt device that we can use for alarms. """
+
+        stub = self.get_stub()
+        logical_devices = stub.ListLogicalDevices(Empty())
+        logical_device_ids = [x.id for x in logical_devices.items]
+
+        devices = stub.ListDevices(Empty())
+
+        for device in devices.items:
+            # If the parent_id is notempty and no a logical_device then it must not be an OLT.
+            if (device.parent_id) and (device.parent_id not in logical_device_ids):
+                print device.parent_id, logical_device_ids
+                continue
+
+            return device. id
+
+        raise Exception("No OLT devices in VOLTHA to choose from")
+
+    def get_onus(self, olt_id):
+        """ Query VOLTHA to get a list of ONUs attached to a particular OLT """
+
+        onus = []
+
+        stub = self.get_stub()
+        devices = stub.ListDevices(Empty())
+        for device in devices.items:
+            if device.parent_id != olt_id:
+                continue
+            if device.parent_port_no is None:
+                continue
+
+            onus.append({"id": olt_id,
+                         "onu_device_id": device.id,
+                         "intf_id": str(device.parent_port_no & 0x0F)})
+
+        return onus
+
+
+class AlarmGenerator(VOLTHAClient):
+    def __init__(self, voltha_grpc, global_request, onus=[], rate=0.1, duration=1):
+        super(AlarmGenerator, self).__init__(voltha_grpc, global_request)
+        self.onus = onus
+        self.rate = rate
+        self.duration = duration
+        self.raised_alarms = []
+
+    def pick_alarm(self):
+        eligible_indicators = ["dying_gasp", "onu_los", "onu_lopc_miss", "onu_lopc_mic", "onu_lob"]
+        while True:
+            onu = random.choice(self.onus)
+            indicator = random.choice(eligible_indicators)
+
+            alarm = copy.copy(onu)
+            alarm["indicator"] = indicator
+
+            # Make sure we don't already have this alarm raised on this ONU. If so, the loop around and try to pick
+            # some other alarm. If all possible alarms are currently raised, eventually we'll keep looping until some
+            # alarm is free.
+            if alarm in self.raised_alarms:
+                time.sleep(0.01)  # Avoid tying up the CPU if all alarms are raised for an extended time.
+                continue
+
+            return alarm
+
+    def clear_alarm(self, kw):
+        if kw in self.raised_alarms:
+            self.raised_alarms.remove(kw)
+
+        kw["operation"] = voltha_pb2.SimulateAlarmRequest.CLEAR
+
+        response = None
+        try:
+            simulate_alarm = voltha_pb2.SimulateAlarmRequest(**kw)
+            stub = self.get_stub()
+            response = stub.SimulateAlarm(simulate_alarm)
+        except Exception as e:
+            self.log.error('Error simulate alarm {}. Error:{}'.format(kw['id'], e), kw=kw)
+            return
+        name = enum2name(common_pb2.OperationResp,
+                        'OperationReturnCode', response.code)
+        self.log.info("Cleared Alarm", alarm=kw, response=name)
+
+    def generate_alarm(self):
+        kw = self.pick_alarm()
+
+        response = None
+        try:
+            simulate_alarm = voltha_pb2.SimulateAlarmRequest(**kw)
+            stub = self.get_stub()
+            response = stub.SimulateAlarm(simulate_alarm)
+        except Exception as e:
+            self.log.error('Error simulate alarm {}. Error:{}'.format(kw['id'], e), kw=kw)
+            return
+        name = enum2name(common_pb2.OperationResp,
+                        'OperationReturnCode', response.code)
+        self.log.info("Generated Alarm", alarm=kw, response=name)
+
+        self.raised_alarms.append(kw)
+
+        Timer(self.duration, functools.partial(self.clear_alarm, kw)).start()
+
+    def run(self):
+        while True:
+            time.sleep(1/self.rate)
+            self.generate_alarm()
+
+
+def main():
+
+    parser = argparse.ArgumentParser()
+
+    _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
+    parser.add_argument(
+        '-C', '--consul', action='store', default=defs['consul'], help=_help)
+
+    _help = 'Lookup Voltha endpoints based on service entries in Consul'
+    parser.add_argument(
+        '-L', '--lookup', action='store_true', help=_help)
+
+    _help = 'All requests to the Voltha gRPC service are global'
+    parser.add_argument(
+        '-G', '--global_request', action='store_true', help=_help)
+
+    _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
+        defs['voltha_grpc_endpoint'])
+    parser.add_argument('-g', '--grpc-endpoint', action='store',
+                        default=defs['voltha_grpc_endpoint'], help=_help)
+
+    _help = 'device id, if None will query VOLTHA for the first device (default %s)' % defs['device_id']
+    parser.add_argument('-d', '--device_id', action='store',
+                        default=defs['device_id'], help=_help)
+
+    _help = 'onu id, if None will query VOLTHA for a set of ONUs  (default: %s)' % defs['onu_id']
+    parser.add_argument('-o', '--onu_id', action='store',
+                        default=defs['onu_id'], help=_help)
+
+    _help = 'intf id  (default: %s)' % defs['intf_id']
+    parser.add_argument('-i', '--intf_id', action='store',
+                        default=defs['intf_id'], help=_help)
+
+    _help = 'rate in alarms per second  (default: %s)' % defs['rate']
+    parser.add_argument('-r', '--rate', action='store', type=float,
+                        default=defs['rate'], help=_help)
+
+    _help = 'duration between raise and clear in seconds (default: %s)' % defs['duration']
+    parser.add_argument('-u', '--duration', action='store', type=int,
+                        default=defs['duration'], help=_help)
+
+    args = parser.parse_args()
+
+    if args.lookup:
+        host = args.consul.split(':')[0].strip()
+        port = int(args.consul.split(':')[1].strip())
+        consul = Consul(host=host, port=port)
+
+        _, services = consul.catalog.service('voltha-grpc')
+        if not services:
+            print('No voltha-grpc service registered in consul; exiting')
+            sys.exit(1)
+        args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
+                                            services[0]['ServicePort'])
+
+        _, services = consul.catalog.service('voltha-sim-rest')
+        if not services:
+            print('No voltha-sim-rest service registered in consul; exiting')
+            sys.exit(1)
+        args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
+                                                services[0]['ServicePort'])
+
+    device_id = args.device_id
+    if not device_id:
+        device_id = VOLTHAClient(args.grpc_endpoint, args.global_request).get_first_olt_device_id()
+
+    if args.onu_id:
+        onus = [{"id": device_id,
+                 "onu_device_id": args.onu_id,
+                 "intf_id": args.intf_id}]
+    else:
+        onus = VOLTHAClient(args.grpc_endpoint, args.global_request).get_onus(device_id)
+        if not onus:
+            raise Exception("Found no valid ONUs in VOLTHA on olt %s. Perhaps use -i and -o options?" % device_id)
+
+    print banner
+
+    g = AlarmGenerator(args.grpc_endpoint,
+                       args.global_request,
+                       onus = onus,
+                       rate=args.rate,
+                       duration=args.duration)
+    g.run()
+
+if __name__ == "__main__":
+    main()
