Skip to content

Commit eebb4c2

Browse files
Initial Commit
0 parents  commit eebb4c2

File tree

10 files changed

+431
-0
lines changed

10 files changed

+431
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
wattx-task

.idea/codeStyleSettings.xml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/libraries/GOPATH__wattx_task_.xml

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/libraries/Go_SDK.xml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/wattx-task.iml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Readme.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Wattx-Task
2+
3+
4+
## Problem Statement
5+
6+
Emulate a heating service in which sensors in a room records temperature and periodically publish readings in a specific format.
7+
After receiving the values, openness of the valve is determined and again published.
8+
9+
## Solution
10+
11+
A message broker is used to publish and subscribe messages in the IOT environment.
12+
Some assumptions are made to emulate the real world scenario.
13+
14+
- A room consists of 10 sensors.
15+
- Every sensors randomly publishes the recorded reading attached to a given topic.
16+
- Every 20 seconds(periodically) a reading is published.
17+
- Currently, the test scenario allows a total of 4 readings ina single run.
18+
19+
## Execution
20+
21+
Set mqtt broker up and running:
22+
```sh
23+
$ docker run -d -p 1883:1883 -p 8883:8883 prologic/mosquitto
24+
25+
```
26+
27+
```
28+
Give examples
29+
```
30+
31+
### Installing
32+
33+
A step by step series of examples that tell you have to get a development env running
34+
35+
Say what the step will be
36+
37+
```
38+
Give the example
39+
```
40+
41+
And repeat
42+
43+
```
44+
until finished
45+
```
46+
47+
End with an example of getting some data out of the system or using it for a little demo
48+
49+
## Running the tests
50+
51+
Explain how to run the automated tests for this system
52+
53+
### Break down into end to end tests
54+
55+
Explain what these tests test and why
56+
57+
```
58+
Give an example
59+
```
60+
61+
### And coding style tests
62+
63+
Explain what these tests test and why
64+
65+
```
66+
Give an example
67+
```
68+
69+
## Deployment
70+
71+
Add additional notes about how to deploy this on a live system
72+
73+
## Built With
74+
75+
* [Dropwizard](http://www.dropwizard.io/1.0.2/docs/) - The web framework used
76+
* [Maven](https://maven.apache.org/) - Dependency Management
77+
* [ROME](https://rometools.github.io/rome/) - Used to generate RSS Feeds
78+
79+
## Contributing
80+
81+
Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us.
82+
83+
## Versioning
84+
85+
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).
86+
87+
## Authors
88+
89+
* **Billie Thompson** - *Initial work* - [PurpleBooth](https://github.com/PurpleBooth)
90+
91+
See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.
92+
93+
## License
94+
95+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
96+
97+
## Acknowledgments
98+
99+
* Hat tip to anyone who's code was used
100+
* Inspiration
101+
* etc

config/brokerConfig.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package config
2+
3+
import (
4+
5+
"github.com/eclipse/paho.mqtt.golang"
6+
)
7+
8+
9+
func Init(conn string) *mqtt.ClientOptions{
10+
11+
return mqtt.NewClientOptions().AddBroker(conn)
12+
}

helper/helper.go

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package helper
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
log "github.com/Sirupsen/logrus"
7+
"math/rand"
8+
"strconv"
9+
"time"
10+
mqtt "github.com/eclipse/paho.mqtt.golang"
11+
"github.com/wattx-task/models"
12+
"os"
13+
"encoding/json"
14+
15+
)
16+
17+
// Publish message on /acuators/room-1 topic
18+
func PubValveValue (str []byte, client mqtt.Client){
19+
20+
token := client.Publish("/actuators/room-1", 0, true, str)
21+
token.Wait()
22+
//str := strings.Replace(str, \, " ", -1)
23+
fmt.Printf("Publishing message on topic: /actuators/room-1 : %v \n", string(str))
24+
25+
}
26+
27+
28+
// Unsubscribe from a topic
29+
func Unsubscribe (broker *models.BrokerSub, client mqtt.Client) error{
30+
31+
if token := client.Unsubscribe(broker.Topic); token.Wait() && token.Error() != nil {
32+
fmt.Println(token.Error())
33+
return token.Error()
34+
}
35+
return nil
36+
}
37+
38+
39+
40+
// Publish message on /readings/temperature
41+
func Publish(broker *models.BrokerPub, client mqtt.Client) error {
42+
43+
if broker.Action != "pub" {
44+
err := errors.New("Invalid setting for action, must be pub")
45+
return err
46+
}
47+
48+
if broker.Topic == "" {
49+
err := errors.New("Invalid setting for topic, must not be empty")
50+
return err
51+
}
52+
53+
token := client.Publish(broker.Topic, 0, true, broker.Payload)
54+
token.Wait()
55+
56+
return nil
57+
58+
}
59+
60+
61+
// Callback on subscriber after receiving message for a given topic
62+
func onMessageRecv(client mqtt.Client, message mqtt.Message){
63+
64+
var temp models.TempReading
65+
if err := json.Unmarshal(message.Payload(), &temp); err != nil {
66+
log.Println(err)
67+
return
68+
}
69+
70+
fmt.Printf("Received message on topic: %v Message: %+v \n ", message.Topic(), string(message.Payload()))
71+
72+
valvePercent := RegulateTemp(temp.Value)
73+
reqNum := fmt.Sprintf("%.2f", valvePercent)
74+
out, err := json.Marshal(reqNum)
75+
if err != nil {
76+
log.Println(err)
77+
return
78+
}
79+
80+
PubValveValue(out,client )
81+
82+
}
83+
84+
// Specifies valve openness in percentages
85+
func RegulateTemp (value float64) float64{
86+
87+
if value> 22 {
88+
return (22 * 100)/ value
89+
}else if value < 22{
90+
return 100.0
91+
}
92+
93+
return 0.0
94+
}
95+
96+
97+
// Subscribes to a given topic
98+
func Subscribe(broker *models.BrokerSub, client mqtt.Client) error {
99+
100+
if broker.Topic == "" {
101+
err := errors.New("Invalid setting for topic, must not be empty")
102+
log.Errorln(err)
103+
os.Exit(1)
104+
}
105+
106+
if token := client.Subscribe(broker.Topic, 0, onMessageRecv); token.Wait() && token.Error() != nil {
107+
fmt.Println(token.Error())
108+
return token.Error()
109+
}
110+
return nil
111+
}
112+
113+
114+
// Generates periodic messages and call publisher
115+
func GenPeriodicTemp(d time.Duration, c mqtt.Client) error {
116+
117+
rand.Seed(time.Now().UTC().UnixNano())
118+
ticker := time.NewTicker(time.Second * 5)
119+
120+
go func() {
121+
for x := range ticker.C{
122+
123+
reqRandTemp := GetRandomfloat(18.0, 25.0)
124+
randomInt := GetRandomInt(0, 10)
125+
randomIntString := fmt.Sprintf("%d", randomInt)
126+
sensorID := "sensorID" + "-" + randomIntString
127+
128+
temp := &models.TempReading{
129+
SensorID: sensorID,
130+
Type: "Temperature",
131+
Value: reqRandTemp,
132+
}
133+
134+
out, err := json.Marshal(temp)
135+
if err != nil {
136+
log.Println(err)
137+
return
138+
}
139+
140+
broker := &models.BrokerPub{
141+
Topic: "/readings/temperature",
142+
Action: "pub",
143+
Payload: string(out),
144+
Num: 1,
145+
}
146+
147+
err = Publish(broker, c)
148+
if err != nil {
149+
err = errors.New("Unable to publish reading")
150+
return
151+
}
152+
fmt.Printf("%+v published at %v \n", broker, x)
153+
154+
}
155+
156+
}()
157+
158+
time.Sleep(time.Second * 20)
159+
ticker.Stop()
160+
161+
return nil
162+
}
163+
164+
// Generates random integer
165+
func GetRandomInt(min int, max int) int {
166+
167+
return min + rand.Intn(max-min)
168+
}
169+
170+
171+
// Generates random float
172+
func GetRandomfloat(mint float64, max float64) float64 {
173+
174+
num := (rand.Float64() * 30) + 7
175+
reqNum := fmt.Sprintf("%.2f", num)
176+
177+
i, err := strconv.ParseFloat(reqNum, 64)
178+
if err != nil {
179+
log.Println(err)
180+
return 0.0
181+
}
182+
return i
183+
}
184+

0 commit comments

Comments
 (0)