Brooke's World The life and ramblings of Brooke.

November 15, 2016

Salt Reactor : Having a minion ask another minion to execute a module with events and reactors

Filed under: Uncategorized — Brooke @ 3:38 pm


I needed to solve the task of having a minion execute a job on another minion and this is how I accomplished the task.  This stemmed from having a minion that runs a web applications which just needed to execute an execution module that already existed, but needed to run on a different minion.

My solution depends on Salt events and reactors to orchestrate the request from the web server minion to the worker minion and have the worker minion give a response of the work it completed back to the web server minion.

Salt version: salt 2016.3.4


Host Salt Role Use Case
saltmast16 Salt Master Orchestrator
saltmina16 Salt Minion Where execution module will run
saltminb16 Salt Minion Web server that initiates work




The event.fire_master call sends the com/millamilla/test/event/finish event to the master


Web Server

 Web Server Files/ Code salmast16


 Master Files/ Code saltmina16


Worker Files/ Code
Send an event from the web server to the master. Send event

import salt.client
import uuid

caller = salt.client.Caller()
event_uuid = str(uuid.uuid1())

      'target': "saltmina16",
      'site': "moodle",
      'user': "hedrickbt",
      'uuid': event_uuid,
Receive event

  # ...
  - 'com/millamilla/test/event/start':        
    - salt://reactor/rhtesteventstart.sls   
  # ...
 >>>>>>>>>>>>>>>>>>>>   >>>>>>>>>>>>>>>>>>>>>>>>>>>>
 Master handles event and causes execuction module to run on worker minion Handle com/millamilla/test/event/start Event.  Call execution module on worker.  /srv/salt/reactor/rhtesteventstart.sls

    - tgt: {{ data['data']['target'] }}
    - arg:
      - {{ data['data']['site'] }}
      - {{ data['data']['user'] }}
      - {{ data['id'] }}
      - {{ data['data']['uuid'] }}


Execute module Created on master:
and sync’d to minions from master via:
salt ‘*’ saltutil.sync_all

import salt

__outputter__ = {
  'rhfunc': 'yaml'

def rhfunc(site, user, requesting_host, event_uuid):
  result = {


  return result
 >>>>>>>>>>>>>>>>>>>  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 After worker minion executes modules send event back to master Receive event

  # ...
  - 'com/millamilla/test/event/finish':
    - salt://reactor/rhtesteventfinish.sls 
  # ...
<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 Forward event Master received to the web minion. Receive/Handle Event



This needs to run just after sending the message so it can be listening.  You will want to add code that has a timeout in the for…print loop.  Otherwise, it could run forever.

You will also want to add code to look at the data[‘uuid’] to make sure it is the one you sent out.

Typically, you wouldn’t have a separate send/receive program, but you can.  I plant to create a single script that generates the uuid, sends the request, and waits for a message to return within a timeout period.  If the timeout is exceeded an error would be thrown.

import salt.config
import salt.utils.event
import socket
import os

# Import 3rd-party libs
import salt.ext.six as six

my_hostname = socket.gethostname()

#opts = salt.config.client_config('/etc/salt/minion')
opts = {}
opts['node'] = 'minion'
opts['sock_dir'] = '/var/run/salt'
opts['sock_dir'] = os.path.join(opts['sock_dir'], opts['node'])
opts['id'] = my_hostname
opts['transport'] = 'zeromq'

event = salt.utils.event.get_event(

for data in event.iter_events(tag='com/millamilla/test/event/finish'):
Handle Event



  - tgt: {{ data['data']['requesting_host'] }}
  - arg:
    - {{ data['data'] }}
    - com/millamilla/test/event/finish
 <<<<<<<<<<<<<<<<<<<  <<<<<<<<<<<<<<<<<<<

February 24, 2015

Contextual Electronics Current Sink or Swim Project – breadboard

I have been taking an online course in electronics called Contextual Electronics with Chris Gammell as the instructor.

We currently are working on a small board that acts as a current sink.  The idea is that by using a potentiometer, op amp, and N channel Mosfet, we can control the amperage that goes into a load ( LED, battery testing, etc. ).

So far we have been creating the schematic, picking parts, and laying out the PCB.  We have been able to get this done in about a month so far.  Next step is to order the boards, probably via OSH Park, order the parts ( Digikey ) for me, assemble, and then test.

My desire to understand how this works better and my eagerness to see something in the physical got the better of me this past weekend.  As a result, I replicated the current control portion of the schematic on a breadboard.

The “active” parts I used are:

Type Part
 Op Amp MCP601 
 N Channel Mosfet  IRF510

These are not the same parts we are using for the course, but they are what I had on hand and wanted to try to understand how the circuit works by being able to probe for voltages, measure current, and “twiddle” the power supply knob to see the impact of higher and lower input voltages.

What I learned is that  by adjusting the input voltage to the Op Amp, it would cause the FET to allow current ( and voltage ) to pass through.  Once the return voltage to the Op Amp reached the input voltage, the Op Amp would not need to let current through.  Then, the return voltage would decrease and the Op Amp would need to let more voltage through again.

From what I can tell, this happens so rapidly you can’t really tell just by using a voltmeter.  I have yet to put it on my oscilloscope to see if I can visualize what is going on.

But, this cycle of the op amp allowing voltage through, the feed back voltage increaseing to meet the input voltage to the op amp and then the op amp decreasing voltage, the feed back voltage decreasing until the op amp increases voltage, just keeps going in a loop….

Until of course, I change the input  voltage via the potentiometer.  This process lets me control the amount of current flowing through the FET by controlling the amount of voltage passing through the op amp.  In effect, I can use low voltage ( like a digital signal ) to control a very high amperage.

In my test, I was only testing from 0 to 135mah.  But, what mattered was that I could see the potentiometer that controlled the op amp input voltage control the FET output amperage.


Breadboard mess with small perfboard for my .1 ohm resistor



Supply voltage

Milliamps passing through FET at near maximum voltage supplied to op amp v+


Voltage making it to v+ ( I have a voltage divider that decreases the voltage from the supply before going into the potentiometer – that is part of another divider).


Video of my hand adjusting the potentiometer to see the current going through the FET decreasing and increasing.

October 3, 2013

Using the tymkrs “Turn Me” with an Arduino

Filed under: Uncategorized — Tags: — Brooke @ 11:24 pm

Here is a quick write up on how to use the tymkrs “Turn Me” rotary encoder.  This supports the “push down” feature of the tymkrs kit.

RotaryEncoderDemo_bb     output_window


Fritzing Rotary Encoder Part: Rotary Encoder with Knob bth.fzpz

Fritzing Project: RotaryEncoderDemo.fzz

Arduino (1.5) project: RotaryEncoderDemo.ino

 /* Read Quadrature Encoder
  * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V.
  * Sketch by max wolf /
  * v. 0.1 - very basic functions - mw 20061220
  * Sketch updated by Brooke Hedrick /
  * v. 0.2 - Added the "S" pin for encoders with push-down support - bth 09292013
  *        - Put a limit of 255 and 0 in place.  It rolls over automatically at the limits - bth 09292013

 int val;
 int encoder0PinA = 3;
 int encoder0PinB = 4;
 int encoder0PinS = 5;
 int encoder0PosUp = 0;
 int encoder0PosDown = 0;
 int encoder0PinALast = LOW;
 int n = LOW;
 int encoder0UpDown = LOW;

 void setup() {
   Serial.begin (9600);

 void loop() {
   encoder0UpDown = digitalRead(encoder0PinS);
   n = digitalRead(encoder0PinA);
   if ((encoder0PinALast == LOW) && (n == HIGH)) {
     //Serial.print("up down:");
     if (digitalRead(encoder0PinB) == LOW) {
       if (encoder0UpDown == LOW) {
         if (encoder0PosUp < 0) {
             encoder0PosUp = 255;
       } else {
         if (encoder0PosDown < 0) {
             encoder0PosDown = 255;
     } else {
       if (encoder0UpDown == LOW) {
         if (encoder0PosUp > 255) {
           encoder0PosUp = 0;
       } else {
         if (encoder0PosDown > 255) {
           encoder0PosDown = 0;
     Serial.print(" ");
   encoder0PinALast = n;

September 28, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 5 : Understanding The Relay Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 12:12 am


  • Create a block diagram for the relay driver circuit.



September 25, 2013

Contextual Electronics : Session 1 : Module 4 : Unit 5 : Choosing Components For The Current/Fan Driver Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:57 pm


Find the following types of components

Recall the following design goals:

  • Swappable components with easy to solder packages.
  • Low cost.
  • SPI DAC part with 8- 10 bits.
  • MOSFET capable of carrying half an amp in a surface mount package.
  • Moderately accurate sense resistor.

September 24, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 4 : Understanding The Current/Fan Driver Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:44 pm


  • Create a current source with a voltage input, using an op amp.
  • Add in an optional DAC to control the current source with voltage readback



Git Repository:

September 22, 2013

Contextual Electronics : Session 1 : Module 4 : Unit 4 : Choosing Components For The Thermocouple Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 8:45 pm


Find the following types of components:

Recall the following design goals:

  • 16+ bit input
  • Low cost
  • 1 degree C accurate (aim for .5 C accurate)
  • Swappable components
  • Easy to solder components

September 21, 2013

Contextual Electronics : Session 1 : Module 3 : Unit 3 : Understanding the Thermocouple Module : Task

Filed under: Uncategorized — Tags: — Brooke @ 11:37 am


  • Create a block diagram for the thermocouple measurement circuit in Kicad.




September 12, 2013

Contextual Electronics : Session 1 : Module 2 : Unit 9 : Creating A Schematic Skeleton : Task

Filed under: Uncategorized — Tags: — Brooke @ 8:50 pm


  1. Create a schematic with a heirarchical page for each block in the block diagram.
  2. Add some hierarchical labels within one of the sheets.
  3. Exit the sheet and import the heirarchical pin to the top level heirarchy symbol.



September 8, 2013

Contextual Electronics : Session 1 : Module 2 : Unit 11: Mechanical Constraints : Task

Filed under: Uncategorized — Tags: — Brooke @ 9:02 pm

Measure or look up the dimension of an Arduino Uno. Compare against other versions of Arduino.

Verify the pin pitch of the stackable connectors on the edge of the Arduino.

Enter the board outline of the Arduino into PCBnew for a rough 2D guideline.


Older Posts »

Powered by WordPress