my haskell controlled offgrid fridge

综合技术 2018-04-22 阅读原文

I'm preparing for a fridge upgrade, away from the tiny propane fridge to a chest freezer conversion. My home computer will be monitoring the fridge temperature and the state of my offgrid energy system, and turning the fridge on and off using a relay and the inverter control board I built earlier.

This kind of automation is a perfect fit for Functional Reactive Programming (FRP) since it's all about time-varying behaviors and events being combined together.

Of course, I want the control code to be as robust as possible, well tested, and easy to modify without making mistakes. Pure functional Haskell code.

There are many Haskell libraries for FRP, and I have not looked at most of them in any detail. I settled on reactive-banana because it has a good reputation and amazing testimonials.

"In the programming-language world, one rule of survival is simple: dance or die. This library makes dancing easy." – Simon Banana Jones

But, it's mostly used for GUI programming, or maybe some musical live-coding. There were no libraries for using reactive-banana for the more staid task of home automation, or anything like that. Also, using it involves a whole lot of IO code, so not great for testing.

So I built reactive-banana-automation on top of it to address my needs. I think it's a pretty good library, although I don't have a deep enough grokking of FRP to say that for sure.

Anyway, it's plenty flexible for my fridge automation needs, and I also wrote a motion-controlled light automation with it to make sure it could be used for something else (and to partly tackle the problem of using real-world time events when the underlying FRP library uses its own notion of time).

The code for my fridge is a work in progress since the fridge has not arrived yet, and because the question of in which situations an offgrid fridge should optimally run and not run is really rather complicated.

Here's a simpler example, for a non-offgrid fridge.

fridge :: Automation Sensors Actuators
fridge sensors actuators = do
        -- Create a Behavior that reflects the most recently reported
        -- temperature of the fridge.
        btemperature <- sensedBehavior (fridgeTemperature sensors)
        -- Calculate when the fridge should turn on and off.
        let bpowerchange = calcpowerchange  btemperature
        onBehaviorChangeMaybe bpowerchange (actuators . FridgePower)
  where
        calcpowerchange (Sensed temp)
                | temp `belowRange` allowedtemp = Just PowerOff
                | temp `aboveRange` allowedtemp = Just PowerOn
                | otherwise = Nothing
        calcpowerchange SensorUnavailable = Nothing
        allowedtemp = Range 1 4

And here the code is being tested in a reproducible fashion:

> runner  runner $ sensors -> fridgeTemperature sensors =: 6
[FridgePower PowerOn]
> runner $ sensors -> fridgeTemperature sensors =: 3
[]
> runner $ sensors -> fridgeTemperature sensors =: 0.5
[FridgePower PowerOff]

BTW, building a 400 line library and writing reams of control code for a fridge that has not been installed yet is what we Haskell programmers call "laziness".

责编内容by:joeyh 【阅读原文】。感谢您的支持!

您可能感兴趣的

Book review: “Programming in Haskell” ... It's hard not to run into Graham Hutton's work when reading about functional programming, so reading a book on Haskell written by him sounded like a g...
Manipulation of signed binary data at Haskell Safe... I'm reading in a struct from a binary file that contains signed 16bit integers using the Get monad from Data.Binary . My current code looks lik...
What is the meaning of a strict version in haskell... Follow , it is said foldl' are strict version of foldl . But it's hard for me to understand , what does strict mean?? foldl f z0 x...
Series Spotlight: Liftoff Series! Learning Haskell, like learning anything, can be a long and sometimes difficult journey. But every journey starts with a first step! And when you tak...
The Future is Functional: Haskell and the AI Nativ... As regular readers of this blog know, I love talking about the future of Haskell as a language. I’m interested in ways we can shape the future of prog...