Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Demo day with digital input readings mapped to displayed statuses
  • Loading branch information
wrr14001 committed Apr 30, 2019
1 parent d1c860c commit 5b9c3d0
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .gitignore
@@ -1,3 +1,3 @@
*.exe
.idea/*

executable/*
6 changes: 3 additions & 3 deletions constants.go
Expand Up @@ -17,9 +17,9 @@ const (
messageReceived = "received"

// Time (in seconds) to wait between performing read/send operations
dataReadPeriod = 300
dataReadPeriod = 60
dataSendPeriod = 300
statusReadPeriod = 300
statusReadPeriod = 1

// Modbus data types
WORD = "WORD"
Expand Down Expand Up @@ -188,7 +188,7 @@ var metrics = [...]Metric{
{
"fuel.pressure",
0,
1000,
100,
},
{
"fuel.temp",
Expand Down
78 changes: 69 additions & 9 deletions modbusManager.go
Expand Up @@ -70,12 +70,12 @@ func (m *_modbusClient) readAllRegisterData() map[string]StampedReading {
intervals := m.readsForAllRegisters() // Modbus reading intervals
var data []byte // Data from modbus

m.lock.Lock() // One reader at a time to be safe
m.lock.Lock() // One reader at a time to be safe
for _, interval := range intervals { // Do readings for all intervals
start := uint16(interval[0])
number := uint16(interval[1])
reading, err := m.conn.ReadHoldingRegisters(start, number) // Read the registers
if err != nil { // Make sure it worked
if err != nil { // Make sure it worked
fmt.Printf("Error reading %v registers starting at %v: %v\n", number, start, err)
continue
}
Expand Down Expand Up @@ -131,6 +131,48 @@ func reverse(s string) string {
return string(runes)
}

func (m *_modbusClient) getDigitalInputs() string {
data := m.readHoldingRegisters(uint16(76), uint16(2))
binstr := make([]string, len(data))
for i := 0; i < len(data); i += 2 {
binstr[i] = reverse(fmt.Sprintf("%08s", strconv.FormatInt(int64(data[i+1]), 2)))
binstr[i+1] = reverse(fmt.Sprintf("%08s", strconv.FormatInt(int64(data[i]), 2)))
}
return strings.Join(binstr, "")
}

func (m *_modbusClient) getDigitalUpdates() map[string]int {
inputs := m.getDigitalInputs()
inputMap := make(map[string]int)
for k, v := range _inputs {
input := inputs[k] - 48
inputMap[v] = int(input)
}
if len(_lastInput) == 0 {
_lastInput = inputMap
return inputMap
} else {
updateMap := inputMap
for k, newv := range inputMap {
oldv, found := _lastInput[k]
if found {
if newv == oldv {
delete(updateMap, k)
}
}
}
for k, v := range updateMap {
_lastInput[k] = v
}

if len(updateMap) > 0 {
fmt.Printf("Digital Input Updates: %v\n", updateMap)
}

return updateMap
}
}

func (m *_modbusClient) getStatusCodes() string {
data := m.readHoldingRegisters(uint16(1499), uint16(16))
binstr := make([]string, len(data))
Expand All @@ -143,7 +185,6 @@ func (m *_modbusClient) getStatusCodes() string {

func (m *_modbusClient) getStatusUpdates() map[string]int {
statuses := m.getStatusCodes()
fmt.Printf("Statuses: %v\n", statuses)
statusMap := make(map[string]int)
for k, v := range _statuses {
status := statuses[k] - 48
Expand All @@ -153,14 +194,23 @@ func (m *_modbusClient) getStatusUpdates() map[string]int {
_lastStatus = statusMap
return statusMap
} else {
updateMap := make(map[string]int)
for k, v := range _lastStatus {
newv := statusMap[k]
if newv != v {
updateMap[k] = newv
updateMap := statusMap
for k, newv := range statusMap {
oldv, found := _lastStatus[k]
if found {
if newv == oldv {
delete(updateMap, k)
}
}
}
_lastStatus = statusMap
for k, v := range updateMap {
_lastStatus[k] = v
}

if len(updateMap) > 0 {
fmt.Printf("Status updates: %v\n", updateMap)
}

return updateMap
}
}
Expand Down Expand Up @@ -230,4 +280,14 @@ var _statuses = map[int]string{
207: "fault.common",
}

var _inputs = map[int]string{
3: "fault.overcrank", // digital input 1
4: "fault.fuel.low",
5: "fault.engine.temp.high",
6: "fault.common",
7: "status.gen.running",
8: "fault.overspeed",
}

var _lastStatus = map[string]int{}
var _lastInput = map[string]int{}
8 changes: 6 additions & 2 deletions server.go
Expand Up @@ -29,7 +29,7 @@ func dataSendLoop() {
func dataReadLoop() { // Read data all day every day
for {
dataBuffer := make(map[string][]StampedReading)
reading := readDummyData() // TODO: error handling
reading := readDummyData() // TODO: error handling
for metric, value := range reading { // Put our data in the buffer
if record, found := dataBuffer[metric]; !found {
dataBuffer[metric] = []StampedReading{value}
Expand All @@ -44,7 +44,11 @@ func dataReadLoop() { // Read data all day every day

func statusReadLoop() { //
for {
updates := readDummyStatuses()
updates := modbusClient.getStatusUpdates()
digitalUpdates := modbusClient.getDigitalUpdates()
for k, v := range digitalUpdates {
updates[k] = v
}
if len(updates) > 0 {
packetData := StatusUpdates{int(time.Now().Unix()), updates}
go socketClient.sendStatusUpdates(packetData) // Sends statuses immediately
Expand Down
12 changes: 6 additions & 6 deletions socketManager.go
Expand Up @@ -47,9 +47,9 @@ func (c *_socketClient) connect() {
c.connLock.Lock() // Shouldn't matter because the other processes will be waiting, but I'm gonna do it anyways
defer c.connLock.Unlock()

rootCAs := x509.NewCertPool() // Initialize a cert pool
rootCert, _ := ioutil.ReadFile("/opt/emulation-server/rootCA.pem") // Read our root CA cert
rootCAs.AppendCertsFromPEM(rootCert) // Add it to the pool
rootCAs := x509.NewCertPool() // Initialize a cert pool
rootCert, _ := ioutil.ReadFile("rootCA.pem") // Read our root CA cert
rootCAs.AppendCertsFromPEM(rootCert) // Add it to the pool

config := &tls.Config{RootCAs: rootCAs} // Trust our root CA

Expand Down Expand Up @@ -114,7 +114,7 @@ func (c *_socketClient) handlePackets() {

func (c *_socketClient) sendPacket(p Packet) {
fmt.Printf("Sending %v packet with ID %v\n", p.Kind, p.ID)
c.connLock.Lock() // Lock to send
c.connLock.Lock() // Lock to send
if err := c.conn.WriteJSON(p); err != nil { // Try to send
fmt.Printf("Error sending %v packet %v: %v\n", p.Kind, p.ID, err) // If we fail, try to reconnect
c.wait.Add(1) // Prevent client things from happening
Expand Down Expand Up @@ -166,7 +166,7 @@ func (c *_socketClient) readIncoming() { // Read messages from gateway
go c.connect() // Reconnect
} else {
switch packet.Kind {
case kindResponse: // Got a response
case kindResponse: // Got a response
go responseManager.received(packet) // Tell the response map
default:
fmt.Printf("Got unknown packet type: %v\n", packet.Kind)
Expand All @@ -178,7 +178,7 @@ func (c *_socketClient) readIncoming() { // Read messages from gateway
func getHeader() http.Header {
h := http.Header{}
h.Set("Content-Type", "application/json")
h.Set(headerUUID, "0000000000000001") // TODO: get this from somewhere
h.Set(headerUUID, "0000000000000004") // TODO: get this from somewhere
h.Set(headerTimestamp, strconv.FormatInt(time.Now().Unix(), 10))
return h
}
Expand Down

0 comments on commit 5b9c3d0

Please sign in to comment.