Compare commits
	
		
			4 commits
		
	
	
		
			e2fc15ed9b
			...
			367e4c43a6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 367e4c43a6 | |||
| 0757ec58a8 | |||
| 051a4bec94 | |||
| ecca05a7e3 | 
					 4 changed files with 60 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -5,12 +5,11 @@
 | 
			
		|||
<link rel="shortcut icon" type="image/png" href="/favicon.png">
 | 
			
		||||
<style>
 | 
			
		||||
body {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    padding: 2em;
 | 
			
		||||
}
 | 
			
		||||
table {
 | 
			
		||||
    font-size: 40px;
 | 
			
		||||
    margin-top: 1em;
 | 
			
		||||
}
 | 
			
		||||
table.status td {
 | 
			
		||||
    width: 2em;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,19 +58,7 @@ td > span {
 | 
			
		|||
<h1>succd</h1>
 | 
			
		||||
<h2>nothing more permanent than a temporary solution</h2>
 | 
			
		||||
 | 
			
		||||
<p style="margin-top: 2em; clear: both;">
 | 
			
		||||
    <table>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th rowspan="2">Pirani Gauge</th>
 | 
			
		||||
            <th>Voltage</th>
 | 
			
		||||
            <td id="volts">{{ .Pirani.Volts }}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>Pressure</th>
 | 
			
		||||
            <td id="mbar">{{ .Pirani.Mbar }}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
<div style="margin: 2em; clear: both; display: grid; grid-template-columns: repeat(auto-fit, minmax(50em, 1fr)); column-gap: 2em; row-gap: 2em;">
 | 
			
		||||
    <table class="status">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>Thresholds</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +83,19 @@ td > span {
 | 
			
		|||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <table>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th rowspan="2">Pirani Gauge</th>
 | 
			
		||||
            <th>Voltage</th>
 | 
			
		||||
            <td id="volts">{{ .Pirani.Volts }}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>Pressure</th>
 | 
			
		||||
            <td id="mbar">{{ .Pirani.Mbar }}</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <table>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th rowspan="3">Control</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -122,13 +122,14 @@ td > span {
 | 
			
		|||
            <th>Status</th>
 | 
			
		||||
            <td id="status" colspan="1">OK</td>
 | 
			
		||||
            <th>Load</th>
 | 
			
		||||
            <td id="load" colspan="1">...</td>
 | 
			
		||||
            <td id="load" colspan="1" style="width: 4em;">...</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
</p>
 | 
			
		||||
<p style="margin-top: 2em;">
 | 
			
		||||
    <canvas id="graph" width="1024" height="512" style="max-width: 100%;"></canvas>
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
    <p>
 | 
			
		||||
        <canvas id="graph" width="1024" height="512" style="max-width: 100%;"></canvas>
 | 
			
		||||
    </p>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p style="font-style: italic; font-size: 12px; margin-top: 5em;">
 | 
			
		||||
    {{ .System.Hostname }} | load: {{ .System.Load }} | <a href="/debug/pprof">pprof</a> | <a href="/metrics">metrics</a> | ws ping: <span id="ping">…</span>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,17 +11,21 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	flagFake                   bool
 | 
			
		||||
	flagListenHTTP             string
 | 
			
		||||
	flagPressureThresholdRough = ScientificNotationValue(1e-1)
 | 
			
		||||
	flagPressureThresholdHigh  = ScientificNotationValue(1e-4)
 | 
			
		||||
	flagFake                             bool
 | 
			
		||||
	flagListenHTTP                       string
 | 
			
		||||
	flagPressureThresholdRough           = ScientificNotationValue(1e-1)
 | 
			
		||||
	flagPressureThresholdRoughHysteresis = ScientificNotationValue(5e-2)
 | 
			
		||||
	flagPressureThresholdHigh            = ScientificNotationValue(1e-4)
 | 
			
		||||
	flagPressureThresholdHighHysteresis  = ScientificNotationValue(5e-5)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	flag.BoolVar(&flagFake, "fake", false, "Enable fake mode which allows to run succd for tests outside the succbone")
 | 
			
		||||
	flag.StringVar(&flagListenHTTP, "listen_http", ":8080", "Address at which to listen for HTTP requests")
 | 
			
		||||
	flag.TextVar(&flagPressureThresholdRough, "pressure_threshold_rough", &flagPressureThresholdRough, "Threshold for opening up diffusion pump (mbar)")
 | 
			
		||||
	flag.TextVar(&flagPressureThresholdRoughHysteresis, "pressure_threshold_rough_hysteresis", &flagPressureThresholdRoughHysteresis, "+-Hysteresis for rough threshold (mbar)")
 | 
			
		||||
	flag.TextVar(&flagPressureThresholdHigh, "pressure_threshold_high", &flagPressureThresholdHigh, "Threshold for enabling high voltage circuits (mbar)")
 | 
			
		||||
	flag.TextVar(&flagPressureThresholdHighHysteresis, "pressure_threshold_high_hysteresis", &flagPressureThresholdHighHysteresis, "+-Hysteresis for high threshold (mbar)")
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
	ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +36,9 @@ func main() {
 | 
			
		|||
	d.daemonState.piraniVolts100.limit = 100
 | 
			
		||||
 | 
			
		||||
	d.aboveRough.threshold = float64(flagPressureThresholdRough)
 | 
			
		||||
	d.aboveRough.hysteresis = float64(flagPressureThresholdRoughHysteresis)
 | 
			
		||||
	d.aboveHigh.threshold = float64(flagPressureThresholdHigh)
 | 
			
		||||
	d.aboveHigh.hysteresis = float64(flagPressureThresholdHighHysteresis)
 | 
			
		||||
	if flagFake {
 | 
			
		||||
		klog.Infof("Starting with fake peripherals")
 | 
			
		||||
		d.adcPirani = &fakeADC{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,13 +30,20 @@ type thresholdOutput struct {
 | 
			
		|||
	debounce time.Time
 | 
			
		||||
	// threshold is the setpoint of the block.
 | 
			
		||||
	threshold float64
 | 
			
		||||
	// hysteresis around the process setpoint (min/max is threshold +- hysteresis)
 | 
			
		||||
	hysteresis float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *thresholdOutput) process(value float64) {
 | 
			
		||||
	if time.Now().Before(t.debounce) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	new := value > t.threshold
 | 
			
		||||
	new := t.output
 | 
			
		||||
	if t.output {
 | 
			
		||||
		new = value > (t.threshold - t.hysteresis)
 | 
			
		||||
	} else {
 | 
			
		||||
		new = value > (t.threshold + t.hysteresis)
 | 
			
		||||
	}
 | 
			
		||||
	if new != t.output {
 | 
			
		||||
		t.output = new
 | 
			
		||||
		t.debounce = time.Now().Add(time.Second * 5)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,20 +26,37 @@ func TestMomentaryOutput(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
func TestThresholdOutput(t *testing.T) {
 | 
			
		||||
	to := thresholdOutput{
 | 
			
		||||
		threshold: 1,
 | 
			
		||||
		threshold:  1,
 | 
			
		||||
		hysteresis: 0.2,
 | 
			
		||||
	}
 | 
			
		||||
	to.process(0)
 | 
			
		||||
	to.process(0.7)
 | 
			
		||||
	if to.output {
 | 
			
		||||
		t.Fatalf("output shouldn't have triggered")
 | 
			
		||||
	}
 | 
			
		||||
	to.process(2)
 | 
			
		||||
	to.process(1)
 | 
			
		||||
	if to.output {
 | 
			
		||||
		t.Fatalf("output shouldn't have triggered")
 | 
			
		||||
	}
 | 
			
		||||
	to.process(1.3)
 | 
			
		||||
	if !to.output {
 | 
			
		||||
		t.Fatalf("output should have triggered")
 | 
			
		||||
	}
 | 
			
		||||
	to.process(0)
 | 
			
		||||
	to.process(1)
 | 
			
		||||
	if !to.output {
 | 
			
		||||
		t.Fatalf("output should have triggered")
 | 
			
		||||
	}
 | 
			
		||||
	to.process(0.7)
 | 
			
		||||
	if !to.output {
 | 
			
		||||
		t.Fatalf("output should have triggered (in debounce)")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// let debounce timeout pass
 | 
			
		||||
	time.Sleep(time.Second * 6)
 | 
			
		||||
 | 
			
		||||
	to.process(0.7)
 | 
			
		||||
	if to.output {
 | 
			
		||||
		t.Fatalf("output shouldn't have triggered")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRingbufferInput(t *testing.T) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue