A simple F# wrapper for C# BACnet library
BACNet is a common and powerful protocol for HVAC. However, it can be overwhelming for someone who just starts to learn BACnet. This repo is to simplifize C# BACnet library to make it easy for getting started with BACnet.
In BACnet, a device is identified by Device ID and each device can contains multiple "points" with identified number and type such as AV-1 AO-0 ... In this repo, a "global" BACnet Point is defined with both Device ID and point type and point number such as 26001 AV-0, the defition is
type ReadResult<'a> = 'a option
type BACnetPoint =
{
PointString : string; // "105123 AV123"for AV point 123 at device 105123
BacnetObj : BacnetObjectId; // be parsed from string
DeviceAdr : BacnetAddress; // be parsed from string
Value : ReadResult<float>; // read from obj and adr
Name : string; // for alias name for the point
}
To parse a string, e.g. "105123 AV-123" to BACnetPoint
, BACnetPoint.parsePointString
can be used
BACnetPoint.parssePointString "105123 av-123"
This will create a BACnetPoint
with Name
field is "".
At startup, all the devices will need to be discovered, Device Store is used to stored all the Device ID and their addresses. In this repo, MailboxProcessor is used for this purpose.
Similar to DeviceStore, MailboxProcess is used. This is to store all pre-defined BACnetPoint.
- Create a BACnet/IP BACnetClient at ip address 192.168.1.11 and discover the network in 10s
let client = FsBACnet.getBACnetClient FsBACnet.BACnetType.BACnetIP "192.168.1.11"
|> FsBACnet.attachOnIAmToClient BACnetDeviceStore.handlerOnIam
BACnetDeviceStoreStatic.buildDeviceStore client 10
- Parse BACnetPoint from string and read their values
["14 av-0";"dev 14 av-2";"dev 14, bv0"]
|> List.map (BACnetPoint.parsePointStringStaticDevStore >> (fun x -> BACnetPointStoreStatic.putPoint x; BACnetPoint.readValue client x))
|> List.iter (fun x -> printfn "`%s` value = %A" x.PointString x.Value)
- Write random number to "Dev 14, av-2" and read all back
let rnd = Random()
BACnetPointStoreStatic.getPoint "14, av-2"
|> Option.get
|> (fun p -> BACnetPoint.writeDisplayResult client p (rnd.NextDouble() |> float32))
|> Async.RunSynchronously
Async.Sleep 1000 |> Async.RunSynchronously
BACnetPointStoreStatic.updateValues client
BACnetPointStoreStatic.getPoints()
|> List.iter (fun x -> printfn "`%s` value = %A" x.PointString x.Value)