Mine updates
diff --git a/README.rst b/README.rst
index 62aa837..2b9f6a0 100644
--- a/README.rst
+++ b/README.rst
@@ -42,6 +42,18 @@
           user: grafana
           password: passwd
 
+Collector setup
+---------------
+
+Used to aggregate dashboards
+
+.. code-block:: yaml
+
+    grafana:
+      collector:
+        enabled: true
+
+
 Client setups
 -------------
 
@@ -98,12 +110,65 @@
     grafana:
       client:
         enabled: true
-        collect_mine: true
+        remote_data:
+          engine: salt_mine
         server:
           host: grafana.host
           port: 3000
           token: token
 
+Usage
+=====
+
+There's a difference between JSON dashboard representation and models we us. Lists are replaced by dictionaries to support mergings and interpolations.
+
+Client enforced dashboards defined in salt-mine
+
+.. code-block:: yaml
+
+    system_metrics:
+      title: graph
+      editable: true
+      hideControls: false
+      rows:
+      - title: Usage
+        height: 250px
+        panels:
+        - title: Panel Title
+          span: 6
+          editable: false
+          type: graph
+          targets: 
+          - refId: A
+            target: "support_prd.cfg01_iot_tcpcloud_eu.cpu.0.idle"
+          datasource: graphite01
+          renderer: flot
+        showTitle: true
+
+
+.. code-block:: yaml
+
+    system_metrics:
+      title: graph
+      editable: true
+      hideControls: false
+      rows:
+      - title: Usage
+        height: 250px
+        panels:
+        - title: Panel Title
+          span: 6
+          editable: false
+          type: graph
+          targets: 
+          - refId: A
+            target: "support_prd.cfg01_iot_tcpcloud_eu.cpu.0.idle"
+          datasource: graphite01
+          renderer: flot
+        showTitle: true
+
+
+
 
 Read more
 =========
diff --git a/grafana/client.sls b/grafana/client.sls
index 7e1e680..6092dde 100644
--- a/grafana/client.sls
+++ b/grafana/client.sls
@@ -35,4 +35,47 @@
 
 {%- endfor %}
 
+{%- set raw_dict = {} %}
+{%- set final_dict = {} %}
+
+{%- if client.remote_data.engine == 'salt_mine' %}
+{%- for node_name, node_grains in salt['mine.get']('*', 'grains.items').iteritems() %}
+{%- if node_grains.grafana is defined %}
+{%- set raw_dict = salt['grains.filter_by']({'default': raw_dict}, merge=node_grains.grafana.get('dashboard', {})) %}
+{%- endif %}
+{%- endfor %}
+{%- endif %}
+
+{%- if client.dashboard is defined %}
+{%- set raw_dict = salt['grains.filter_by']({'default': raw_dict}, merge=client.dashboard) %}
+{%- endif %}
+
+{%- for dashboard_name, dashboard in raw_dict.iteritems() %}
+{%- set rows = [] %}
+{%- for row_name, row in dashboard.get('row', {}).iteritems() %}
+{%- set panels = [] %}
+{%- for panel_name, panel in row.get('panel', {}).iteritems() %}
+{%- set targets = [] %}
+{%- for target_name, target in panel.get('target', {}).iteritems() %}
+{%- do targets.extend([target]) %}
+{%- endfor %}
+{%- do panel.update({'targets': targets}) %}
+{%- do panels.extend([panel]) %}
+{%- endfor %}
+{%- do row.update({'panels': panels}) %}
+{%- do rows.extend([row]) %}
+{%- endfor %}
+{%- do dashboard.update({'rows': rows}) %}
+{%- do final_dict.update({dashboard_name: dashboard}) %}
+{%- endfor %}
+
+{%- for dashboard_name, dashboard in final_dict.iteritems() %}
+
+grafana_client_dashboard_{{ dashboard_name }}:
+  grafana_dashboard.present:
+  - name: {{ dashboard_name }}
+  - dashboard: {{ dashboard }}
+
+{%- endfor %}
+
 {%- endif %}
diff --git a/grafana/collector.sls b/grafana/collector.sls
new file mode 100644
index 0000000..b1f76b1
--- /dev/null
+++ b/grafana/collector.sls
@@ -0,0 +1,50 @@
+{%- from "grafana/map.jinja" import collector with context %}
+{%- if collector.enabled %}
+
+grafana_grains_dir:
+  file.directory:
+  - name: /etc/salt/grains.d
+  - mode: 700
+  - makedirs: true
+  - user: root
+
+{%- set service_grains = {} %}
+
+{# Loading the other service support metadata for localhost #}
+
+{%- for service_name, service in pillar.iteritems() %}
+
+{%- macro load_grains_file(grains_fragment_file) %}{% include grains_fragment_file ignore missing %}{% endmacro %}
+
+{%- set grains_fragment_file = service_name+'/meta/grafana.yml' %}
+{%- set grains_yaml = load_grains_file(grains_fragment_file)|load_yaml %}
+{%- set service_grains = salt['grains.filter_by']({'default': service_grains}, merge=grains_yaml) %}
+
+{%- endfor %}
+
+grafana_grain:
+  file.managed:
+  - name: /etc/salt/grains.d/grafana
+  - source: salt://grafana/files/grafana.grain
+  - template: jinja
+  - user: root
+  - mode: 600
+  - defaults:
+    service_grains:
+      grafana: {{ service_grains|yaml }}
+  - require:
+    - file: grafana_grains_dir
+
+grafana_grains_file:
+  cmd.wait:
+  - name: cat /etc/salt/grains.d/* > /etc/salt/grains
+  - watch:
+    - file: grafana_grain
+
+grafana_grains_publish:
+  module.run:
+  - name: mine.update
+  - watch:
+    - cmd: grafana_grains_file
+
+{%- endif %}
diff --git a/grafana/files/grafana.grain b/grafana/files/grafana.grain
new file mode 100644
index 0000000..3e3b373
--- /dev/null
+++ b/grafana/files/grafana.grain
@@ -0,0 +1 @@
+{{ service_grains|yaml(False) }}
diff --git a/grafana/init.sls b/grafana/init.sls
index 9562a07..9829b7f 100644
--- a/grafana/init.sls
+++ b/grafana/init.sls
@@ -7,4 +7,7 @@
 {%- if pillar.grafana.client is defined %}
 - grafana.client
 {%- endif %}
+{%- if pillar.grafana.collector is defined %}
+- grafana.collector
+{%- endif %}
 {%- endif %}
diff --git a/grafana/map.jinja b/grafana/map.jinja
index baeab61..5c304ea 100644
--- a/grafana/map.jinja
+++ b/grafana/map.jinja
@@ -26,6 +26,8 @@
   server:
     host: 127.0.0.1
     port: 3000
+  remote_data:
+    engine: none
   datasource: {}
   dashboard: {}
 {%- endload %}
diff --git a/grafana/meta/grafana.yml b/grafana/meta/grafana.yml
new file mode 100644
index 0000000..3a8b02d
--- /dev/null
+++ b/grafana/meta/grafana.yml
@@ -0,0 +1,45 @@
+{%- if pillar.get('grafana').collector is defined %}
+dashboard:
+  test-single-{{ grains.host }}:
+    title: Dashboard single {{ grains.host }}
+    editable: true
+    hideControls: false
+    row:
+      single:
+        title: Single row
+        height: 250px
+        showTitle: true
+        panel:
+          first:
+            title: Single Panel
+            span: 8
+            editable: false
+            type: graph
+            target:
+              A:
+                refId: A
+                target: "support_prd.cfg01_iot_tcpcloud_eu.cpu.0.idle"
+            datasource: graphite01
+            renderer: flot
+  test-merge:
+    title: Dashboard merge
+    editable: true
+    hideControls: false
+    row:
+      merge:
+        showTitle: true
+        title: Merge
+        height: 250px
+        panel:
+          merge:
+            title: Merge Panel
+            span: 8
+            editable: false
+            type: graph
+            target:
+              {{ grains.host }}:
+                refId: A
+                target: "support_prd.cfg01_iot_tcpcloud_eu.cpu.0.idle"
+            datasource: graphite01
+            renderer: flot
+{%- endif %}
\ No newline at end of file