{"id":191736,"name":"GridWorks SpaceHeat SCADA","description":"Intended for running a heat pump thermal storage space heating system in a house, and doing this transactively.","url":"https://github.com/thegridelectric/gridworks-scada","last_synced_at":"2026-05-15T23:30:22.120Z","repository":{"id":36992925,"uuid":"492994913","full_name":"thegridelectric/gridworks-scada","owner":"thegridelectric","description":"GridWorks SCADA for space heating","archived":false,"fork":false,"pushed_at":"2026-05-12T12:29:25.000Z","size":6787,"stargazers_count":6,"open_issues_count":47,"forks_count":2,"subscribers_count":5,"default_branch":"dev","last_synced_at":"2026-05-12T13:36:25.878Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thegridelectric.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-16T20:48:04.000Z","updated_at":"2026-05-07T08:44:45.000Z","dependencies_parsed_at":"2026-03-26T23:02:35.796Z","dependency_job_id":null,"html_url":"https://github.com/thegridelectric/gridworks-scada","commit_stats":{"total_commits":966,"total_committers":6,"mean_commits":161.0,"dds":0.4782608695652174,"last_synced_commit":"4dad6afa246227d05e6df64438bcd25515656d25"},"previous_names":["thegridelectric/gridworks-scada","thegridelectric/gw-scada-spaceheat-python"],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/thegridelectric/gridworks-scada","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thegridelectric","download_url":"https://codeload.github.com/thegridelectric/gridworks-scada/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32958607,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T09:19:52.626Z","status":"ssl_error","status_checked_at":"2026-05-12T09:17:33.438Z","response_time":102,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"thegridelectric","name":"GridWorks","uuid":"20042700","kind":"organization","description":"GridWorks is an agent-based, scalable and secure system for decarbonizing power grids.","email":"gridworks@gridworks-consulting.com","website":null,"location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/20042700?v=4","repositories_count":7,"last_synced_at":"2023-03-03T23:15:06.930Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/thegridelectric","funding_links":[],"total_stars":null,"followers":null,"following":null,"created_at":"2022-11-14T06:28:03.880Z","updated_at":"2023-03-03T23:15:06.980Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thegridelectric","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thegridelectric/repositories"},"packages":[],"commits":{"id":9348063,"full_name":"thegridelectric/gridworks-scada","default_branch":"main","total_commits":2276,"total_committers":6,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":379.3333333333333,"dds":0.5557996485061512,"past_year_total_commits":430,"past_year_total_committers":3,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":143.33333333333334,"past_year_dds":0.4976744186046511,"last_synced_at":"2026-05-12T22:02:18.461Z","last_synced_commit":"f38403cd41d9ba1bb07fe29885a520f19810157a","created_at":"2025-03-26T22:32:01.595Z","updated_at":"2026-05-12T22:02:14.942Z","committers":[{"name":"Jessica Millar","email":"jessica.lynn.millar@gmail.com","login":"jessicamillar","count":1011},{"name":"thdfw","email":"th.defauw@gmail.com","login":"thdfw","count":670},{"name":"Andrew Schweitzer","email":"schweitz72@gmail.com","login":"anschweitzer","count":516},{"name":"stickler-ci","email":"support@stickler-ci.com","login":"stickler-ci","count":63},{"name":"Preethi Vaidyanathan","email":"preethi@gaia-scope.com","login":null,"count":15},{"name":"Jessica Millar","email":"jessica@jessica.local","login":null,"count":1}],"past_year_committers":[{"name":"thdfw","email":"th.defauw@gmail.com","login":"thdfw","count":216},{"name":"Jessica Millar","email":"jessica.lynn.millar@gmail.com","login":"jessicamillar","count":141},{"name":"Andrew Schweitzer","email":"schweitz72@gmail.com","login":"anschweitzer","count":73}],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-05-14T00:00:09.630Z","repositories_count":6234191,"commits_count":894481617,"contributors_count":34897894,"owners_count":1153045,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"thegridelectric/gridworks-scada","html_url":"https://github.com/thegridelectric/gridworks-scada","last_synced_at":"2026-05-08T20:00:28.360Z","status":"active","issues_count":7,"pull_requests_count":155,"avg_time_to_close_issue":90635.5,"avg_time_to_close_pull_request":187671.47107438016,"issues_closed_count":2,"pull_requests_closed_count":121,"pull_request_authors_count":3,"issue_authors_count":2,"avg_comments_per_issue":0.5714285714285714,"avg_comments_per_pull_request":0.16129032258064516,"merged_pull_requests_count":103,"bot_issues_count":0,"bot_pull_requests_count":0,"past_year_issues_count":7,"past_year_pull_requests_count":119,"past_year_avg_time_to_close_issue":90635.5,"past_year_avg_time_to_close_pull_request":194571.3023255814,"past_year_issues_closed_count":2,"past_year_pull_requests_closed_count":86,"past_year_pull_request_authors_count":3,"past_year_issue_authors_count":2,"past_year_avg_comments_per_issue":0.5714285714285714,"past_year_avg_comments_per_pull_request":0.19327731092436976,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":73,"created_at":"2025-03-26T22:32:02.177Z","updated_at":"2026-05-08T20:00:28.360Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/thegridelectric%2Fgridworks-scada/issues","issue_labels_count":{"admin":3,"ops":3},"pull_request_labels_count":{"DRAFT PR":2,"admin":2,"ops":2},"issue_author_associations_count":{"COLLABORATOR":7},"pull_request_author_associations_count":{"COLLABORATOR":106,"CONTRIBUTOR":49},"issue_authors":{"anschweitzer":6,"jessicamillar":1},"pull_request_authors":{"jessicamillar":67,"thdfw":49,"anschweitzer":39},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-05-12T00:00:09.018Z","repositories_count":14586026,"issues_count":34341780,"pull_requests_count":112438824,"authors_count":11260137,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{"admin":3,"ops":3},"past_year_pull_request_labels_count":{"admin":2,"DRAFT PR":2,"ops":2},"past_year_issue_author_associations_count":{"COLLABORATOR":7},"past_year_pull_request_author_associations_count":{"COLLABORATOR":74,"CONTRIBUTOR":45},"past_year_issue_authors":{"anschweitzer":6,"jessicamillar":1},"past_year_pull_request_authors":{"jessicamillar":47,"thdfw":45,"anschweitzer":27},"maintainers":[{"login":"jessicamillar","count":68,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jessicamillar"},{"login":"anschweitzer","count":45,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/anschweitzer"}],"active_maintainers":[{"login":"jessicamillar","count":48,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jessicamillar"},{"login":"anschweitzer","count":33,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/anschweitzer"}]},"events":{"total":{"ReleaseEvent":14,"DeleteEvent":72,"PullRequestEvent":111,"IssuesEvent":6,"WatchEvent":1,"IssueCommentEvent":20,"PushEvent":554,"PullRequestReviewCommentEvent":4,"PullRequestReviewEvent":8,"CreateEvent":87},"last_year":{"ReleaseEvent":14,"DeleteEvent":65,"PullRequestEvent":99,"IssuesEvent":6,"WatchEvent":1,"IssueCommentEvent":20,"PushEvent":400,"PullRequestReviewCommentEvent":4,"PullRequestReviewEvent":8,"CreateEvent":77}},"keywords":[],"dependencies":[{"ecosystem":"pypi","filepath":"gw_spaceheat/requirements/base.txt","sha":null,"kind":"lockfile","created_at":"2022-07-08T07:43:33.596Z","updated_at":"2022-07-08T07:43:33.596Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/gw_spaceheat/requirements/base.txt","dependencies":[{"id":119882284,"package_name":"numpy","ecosystem":"pypi","requirements":"==1.22.4","direct":false,"kind":"runtime","optional":false},{"id":119882287,"package_name":"paho-mqtt","ecosystem":"pypi","requirements":"==1.6.1","direct":false,"kind":"runtime","optional":false},{"id":119882289,"package_name":"pendulum","ecosystem":"pypi","requirements":"==2.1.2","direct":false,"kind":"runtime","optional":false},{"id":119882290,"package_name":"pika","ecosystem":"pypi","requirements":"==1.1.0","direct":false,"kind":"runtime","optional":false},{"id":119882292,"package_name":"python-dateutil","ecosystem":"pypi","requirements":"==2.8.2","direct":false,"kind":"runtime","optional":false},{"id":119882294,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"==0.20.0","direct":false,"kind":"runtime","optional":false},{"id":119882295,"package_name":"pytz","ecosystem":"pypi","requirements":"==2022.1","direct":false,"kind":"runtime","optional":false},{"id":119882297,"package_name":"pytzdata","ecosystem":"pypi","requirements":"==2020.1","direct":false,"kind":"runtime","optional":false},{"id":119882299,"package_name":"six","ecosystem":"pypi","requirements":"==1.16.0","direct":false,"kind":"runtime","optional":false}]},{"ecosystem":"pypi","filepath":"gw_spaceheat/requirements/drivers.txt","sha":null,"kind":"lockfile","created_at":"2022-07-08T07:43:33.781Z","updated_at":"2022-07-08T07:43:33.781Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/gw_spaceheat/requirements/drivers.txt","dependencies":[{"id":119882654,"package_name":"numpy","ecosystem":"pypi","requirements":"==1.22.4","direct":false,"kind":"runtime","optional":false},{"id":119882655,"package_name":"paho-mqtt","ecosystem":"pypi","requirements":"==1.6.1","direct":false,"kind":"runtime","optional":false},{"id":119882656,"package_name":"pendulum","ecosystem":"pypi","requirements":"==2.1.2","direct":false,"kind":"runtime","optional":false},{"id":119882657,"package_name":"pika","ecosystem":"pypi","requirements":"==1.1.0","direct":false,"kind":"runtime","optional":false},{"id":119882658,"package_name":"pymodbus","ecosystem":"pypi","requirements":"==2.5.3","direct":false,"kind":"runtime","optional":false},{"id":119882659,"package_name":"pyserial","ecosystem":"pypi","requirements":"==3.5","direct":false,"kind":"runtime","optional":false},{"id":119882660,"package_name":"python-dateutil","ecosystem":"pypi","requirements":"==2.8.2","direct":false,"kind":"runtime","optional":false},{"id":119882661,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"==0.20.0","direct":false,"kind":"runtime","optional":false},{"id":119882662,"package_name":"pytz","ecosystem":"pypi","requirements":"==2022.1","direct":false,"kind":"runtime","optional":false},{"id":119882663,"package_name":"pytzdata","ecosystem":"pypi","requirements":"==2020.1","direct":false,"kind":"runtime","optional":false},{"id":119882664,"package_name":"six","ecosystem":"pypi","requirements":"==1.16.0","direct":false,"kind":"runtime","optional":false},{"id":119882665,"package_name":"smbus2","ecosystem":"pypi","requirements":"==0.4.1","direct":false,"kind":"runtime","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/ci.yaml","sha":null,"kind":"manifest","created_at":"2023-01-17T12:00:58.912Z","updated_at":"2023-01-17T12:00:58.912Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/.github/workflows/ci.yaml","dependencies":[{"id":6988078763,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":6988078764,"package_name":"namoshek/mosquitto-github-action","ecosystem":"actions","requirements":"v1","direct":true,"kind":"composite","optional":false},{"id":6988078765,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":6988078766,"package_name":"canastro/copy-file-action","ecosystem":"actions","requirements":"master","direct":true,"kind":"composite","optional":false},{"id":6988078767,"package_name":"actions/upload-artifact","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":6988078768,"package_name":"actions/download-artifact","ecosystem":"actions","requirements":"v2","direct":true,"kind":"composite","optional":false},{"id":6988078769,"package_name":"codecov/codecov-action","ecosystem":"actions","requirements":"v3.1.0","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"pypi","filepath":"gw_spaceheat/requirements/dev.txt","sha":null,"kind":"manifest","created_at":"2023-01-17T12:00:59.037Z","updated_at":"2023-01-17T12:00:59.037Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/gw_spaceheat/requirements/dev.txt","dependencies":[{"id":6988079984,"package_name":"appnope","ecosystem":"pypi","requirements":"==0.1.3","direct":true,"kind":"development","optional":false},{"id":6988079988,"package_name":"asttokens","ecosystem":"pypi","requirements":"==2.0.5","direct":true,"kind":"development","optional":false},{"id":6988079991,"package_name":"attrs","ecosystem":"pypi","requirements":"==21.4.0","direct":true,"kind":"development","optional":false},{"id":6988079994,"package_name":"backcall","ecosystem":"pypi","requirements":"==0.2.0","direct":true,"kind":"development","optional":false},{"id":6988079997,"package_name":"black","ecosystem":"pypi","requirements":"==22.3.0","direct":true,"kind":"development","optional":false},{"id":6988080000,"package_name":"build","ecosystem":"pypi","requirements":"==0.8.0","direct":true,"kind":"development","optional":false},{"id":6988080004,"package_name":"certifi","ecosystem":"pypi","requirements":"==2022.9.14","direct":true,"kind":"development","optional":false},{"id":6988080008,"package_name":"charset-normalizer","ecosystem":"pypi","requirements":"==2.1.1","direct":true,"kind":"development","optional":false},{"id":6988080011,"package_name":"click","ecosystem":"pypi","requirements":"==8.1.3","direct":true,"kind":"development","optional":false},{"id":6988080014,"package_name":"commonmark","ecosystem":"pypi","requirements":"==0.9.1","direct":true,"kind":"development","optional":false},{"id":6988080017,"package_name":"coverage","ecosystem":"pypi","requirements":"==6.4.1","direct":true,"kind":"development","optional":false},{"id":6988080020,"package_name":"decorator","ecosystem":"pypi","requirements":"==5.1.1","direct":true,"kind":"development","optional":false},{"id":6988080024,"package_name":"docutils","ecosystem":"pypi","requirements":"==0.19","direct":true,"kind":"development","optional":false},{"id":6988080026,"package_name":"executing","ecosystem":"pypi","requirements":"==0.8.3","direct":true,"kind":"development","optional":false},{"id":6988080029,"package_name":"gridworks-protocol","ecosystem":"pypi","requirements":"==0.2.2","direct":true,"kind":"development","optional":false},{"id":6988080032,"package_name":"idna","ecosystem":"pypi","requirements":"==3.4","direct":true,"kind":"development","optional":false},{"id":6988080035,"package_name":"iniconfig","ecosystem":"pypi","requirements":"==1.1.1","direct":true,"kind":"development","optional":false},{"id":6988080038,"package_name":"ipython","ecosystem":"pypi","requirements":"==8.0.0","direct":true,"kind":"development","optional":false},{"id":6988080040,"package_name":"isort","ecosystem":"pypi","requirements":"==5.10.1","direct":true,"kind":"development","optional":false},{"id":6988080043,"package_name":"jedi","ecosystem":"pypi","requirements":"==0.18.1","direct":true,"kind":"development","optional":false},{"id":6988080046,"package_name":"matplotlib-inline","ecosystem":"pypi","requirements":"==0.1.3","direct":true,"kind":"development","optional":false},{"id":6988080049,"package_name":"mypy","ecosystem":"pypi","requirements":"==0.961","direct":true,"kind":"development","optional":false},{"id":6988080051,"package_name":"mypy-extensions","ecosystem":"pypi","requirements":"==0.4.3","direct":true,"kind":"development","optional":false},{"id":6988080054,"package_name":"nose","ecosystem":"pypi","requirements":"==1.3.7","direct":true,"kind":"development","optional":false},{"id":6988080092,"package_name":"numpy","ecosystem":"pypi","requirements":"==1.22.4","direct":true,"kind":"development","optional":false},{"id":6988080097,"package_name":"packaging","ecosystem":"pypi","requirements":"==21.3","direct":true,"kind":"development","optional":false},{"id":6988080098,"package_name":"paho-mqtt","ecosystem":"pypi","requirements":"==1.6.1","direct":true,"kind":"development","optional":false},{"id":6988080101,"package_name":"parso","ecosystem":"pypi","requirements":"==0.8.3","direct":true,"kind":"development","optional":false},{"id":6988080102,"package_name":"pathspec","ecosystem":"pypi","requirements":"==0.9.0","direct":true,"kind":"development","optional":false},{"id":6988080105,"package_name":"pendulum","ecosystem":"pypi","requirements":"==2.1.2","direct":true,"kind":"development","optional":false},{"id":6988080218,"package_name":"pep517","ecosystem":"pypi","requirements":"==0.12.0","direct":true,"kind":"development","optional":false},{"id":6988080225,"package_name":"pexpect","ecosystem":"pypi","requirements":"==4.8.0","direct":true,"kind":"development","optional":false},{"id":6988080227,"package_name":"pickleshare","ecosystem":"pypi","requirements":"==0.7.5","direct":true,"kind":"development","optional":false},{"id":6988080230,"package_name":"pika","ecosystem":"pypi","requirements":"==1.1.0","direct":true,"kind":"development","optional":false},{"id":6988080232,"package_name":"pip-tools","ecosystem":"pypi","requirements":"==6.9.0","direct":true,"kind":"development","optional":false},{"id":6988080235,"package_name":"platformdirs","ecosystem":"pypi","requirements":"==2.5.2","direct":true,"kind":"development","optional":false},{"id":6988080237,"package_name":"pluggy","ecosystem":"pypi","requirements":"==1.0.0","direct":true,"kind":"development","optional":false},{"id":6988080239,"package_name":"prompt-toolkit","ecosystem":"pypi","requirements":"==3.0.29","direct":true,"kind":"development","optional":false},{"id":6988080241,"package_name":"ptyprocess","ecosystem":"pypi","requirements":"==0.7.0","direct":true,"kind":"development","optional":false},{"id":6988080243,"package_name":"pure-eval","ecosystem":"pypi","requirements":"==0.2.2","direct":true,"kind":"development","optional":false},{"id":6988080245,"package_name":"py","ecosystem":"pypi","requirements":"==1.11.0","direct":true,"kind":"development","optional":false},{"id":6988080247,"package_name":"pydantic","ecosystem":"pypi","requirements":"==1.10.2","direct":true,"kind":"development","optional":false},{"id":6988080249,"package_name":"pygments","ecosystem":"pypi","requirements":"==2.12.0","direct":true,"kind":"development","optional":false},{"id":6988080251,"package_name":"pymodbus","ecosystem":"pypi","requirements":"==2.5.3","direct":true,"kind":"development","optional":false},{"id":6988080262,"package_name":"pyparsing","ecosystem":"pypi","requirements":"==3.0.9","direct":true,"kind":"development","optional":false},{"id":6988080264,"package_name":"pyserial","ecosystem":"pypi","requirements":"==3.5","direct":true,"kind":"development","optional":false},{"id":6988080267,"package_name":"pytest","ecosystem":"pypi","requirements":"==7.1.2","direct":true,"kind":"development","optional":false},{"id":6988080269,"package_name":"pytest-asyncio","ecosystem":"pypi","requirements":"==0.19.0","direct":true,"kind":"development","optional":false},{"id":6988080271,"package_name":"pytest-sugar","ecosystem":"pypi","requirements":"==0.9.5","direct":true,"kind":"development","optional":false},{"id":6988080276,"package_name":"python-dateutil","ecosystem":"pypi","requirements":"==2.8.2","direct":true,"kind":"development","optional":false},{"id":6988080278,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"==0.20.0","direct":true,"kind":"development","optional":false},{"id":6988080280,"package_name":"pytz","ecosystem":"pypi","requirements":"==2022.1","direct":true,"kind":"development","optional":false},{"id":6988080282,"package_name":"pytzdata","ecosystem":"pypi","requirements":"==2020.1","direct":true,"kind":"development","optional":false},{"id":6988080284,"package_name":"requests","ecosystem":"pypi","requirements":"==2.28.1","direct":true,"kind":"development","optional":false},{"id":6988080287,"package_name":"result","ecosystem":"pypi","requirements":"==0.8.0","direct":true,"kind":"development","optional":false},{"id":6988080324,"package_name":"rich","ecosystem":"pypi","requirements":"==12.5.1","direct":true,"kind":"development","optional":false},{"id":6988080326,"package_name":"rich-cli","ecosystem":"pypi","requirements":"==1.8.0","direct":true,"kind":"development","optional":false},{"id":6988080356,"package_name":"rich-rst","ecosystem":"pypi","requirements":"==1.1.7","direct":true,"kind":"development","optional":false},{"id":6988080376,"package_name":"six","ecosystem":"pypi","requirements":"==1.16.0","direct":true,"kind":"development","optional":false},{"id":6988080380,"package_name":"smbus2","ecosystem":"pypi","requirements":"==0.4.1","direct":true,"kind":"development","optional":false},{"id":6988080479,"package_name":"stack-data","ecosystem":"pypi","requirements":"==0.2.0","direct":true,"kind":"development","optional":false},{"id":6988080483,"package_name":"termcolor","ecosystem":"pypi","requirements":"==1.1.0","direct":true,"kind":"development","optional":false},{"id":6988080486,"package_name":"textual","ecosystem":"pypi","requirements":"==0.1.18","direct":true,"kind":"development","optional":false},{"id":6988080490,"package_name":"tomli","ecosystem":"pypi","requirements":"==2.0.1","direct":true,"kind":"development","optional":false},{"id":6988080493,"package_name":"traitlets","ecosystem":"pypi","requirements":"==5.1.1","direct":true,"kind":"development","optional":false},{"id":6988080495,"package_name":"typing-extensions","ecosystem":"pypi","requirements":"==4.2.0","direct":true,"kind":"development","optional":false},{"id":6988080499,"package_name":"urllib3","ecosystem":"pypi","requirements":"==1.26.12","direct":true,"kind":"development","optional":false},{"id":6988080502,"package_name":"wcwidth","ecosystem":"pypi","requirements":"==0.2.5","direct":true,"kind":"development","optional":false},{"id":6988080505,"package_name":"wheel","ecosystem":"pypi","requirements":"==0.37.1","direct":true,"kind":"development","optional":false},{"id":6988080508,"package_name":"xdg","ecosystem":"pypi","requirements":"==5.1.1","direct":true,"kind":"development","optional":false}]},{"ecosystem":"pypi","filepath":"gw_spaceheat/requirements/test.txt","sha":null,"kind":"manifest","created_at":"2023-01-17T12:00:59.175Z","updated_at":"2023-01-17T12:00:59.175Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/gw_spaceheat/requirements/test.txt","dependencies":[{"id":6988081923,"package_name":"attrs","ecosystem":"pypi","requirements":"==21.4.0","direct":true,"kind":"test","optional":false},{"id":6988081924,"package_name":"black","ecosystem":"pypi","requirements":"==22.3.0","direct":true,"kind":"test","optional":false},{"id":6988081925,"package_name":"click","ecosystem":"pypi","requirements":"==8.1.3","direct":true,"kind":"test","optional":false},{"id":6988081926,"package_name":"coverage","ecosystem":"pypi","requirements":"==6.4.1","direct":true,"kind":"test","optional":false},{"id":6988081927,"package_name":"iniconfig","ecosystem":"pypi","requirements":"==1.1.1","direct":true,"kind":"test","optional":false},{"id":6988081928,"package_name":"mypy","ecosystem":"pypi","requirements":"==0.961","direct":true,"kind":"test","optional":false},{"id":6988081929,"package_name":"mypy-extensions","ecosystem":"pypi","requirements":"==0.4.3","direct":true,"kind":"test","optional":false},{"id":6988081930,"package_name":"nose","ecosystem":"pypi","requirements":"==1.3.7","direct":true,"kind":"test","optional":false},{"id":6988081931,"package_name":"packaging","ecosystem":"pypi","requirements":"==21.3","direct":true,"kind":"test","optional":false},{"id":6988081932,"package_name":"pathspec","ecosystem":"pypi","requirements":"==0.9.0","direct":true,"kind":"test","optional":false},{"id":6988081933,"package_name":"platformdirs","ecosystem":"pypi","requirements":"==2.5.2","direct":true,"kind":"test","optional":false},{"id":6988081934,"package_name":"pluggy","ecosystem":"pypi","requirements":"==1.0.0","direct":true,"kind":"test","optional":false},{"id":6988081935,"package_name":"py","ecosystem":"pypi","requirements":"==1.11.0","direct":true,"kind":"test","optional":false},{"id":6988081936,"package_name":"pyparsing","ecosystem":"pypi","requirements":"==3.0.9","direct":true,"kind":"test","optional":false},{"id":6988081937,"package_name":"pytest","ecosystem":"pypi","requirements":"==7.1.2","direct":true,"kind":"test","optional":false},{"id":6988081938,"package_name":"pytest-asyncio","ecosystem":"pypi","requirements":"==0.19.0","direct":true,"kind":"test","optional":false},{"id":6988081939,"package_name":"tomli","ecosystem":"pypi","requirements":"==2.0.1","direct":true,"kind":"test","optional":false},{"id":6988081940,"package_name":"typing-extensions","ecosystem":"pypi","requirements":"==4.2.0","direct":true,"kind":"test","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/release.yml","sha":null,"kind":"manifest","created_at":"2026-01-20T13:07:03.727Z","updated_at":"2026-01-20T13:07:03.727Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/.github/workflows/release.yml","dependencies":[{"id":25800545819,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false},{"id":25800545820,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v5.6.0","direct":true,"kind":"composite","optional":false},{"id":25800545821,"package_name":"astral-sh/setup-uv","ecosystem":"actions","requirements":"v6","direct":true,"kind":"composite","optional":false},{"id":25800545822,"package_name":"salsify/action-detect-and-tag-new-version","ecosystem":"actions","requirements":"v2.0.3","direct":true,"kind":"composite","optional":false},{"id":25800545823,"package_name":"release-drafter/release-drafter","ecosystem":"actions","requirements":"v6.0.0","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"pypi","filepath":"packages/gridworks-admin/pyproject.toml","sha":null,"kind":"manifest","created_at":"2026-01-20T13:07:04.046Z","updated_at":"2026-01-20T13:07:04.046Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/packages/gridworks-admin/pyproject.toml","dependencies":[{"id":25800545826,"package_name":"gridworks-proactor","ecosystem":"pypi","requirements":"\u003e=4.1.9","direct":true,"kind":"runtime","optional":false},{"id":25800545828,"package_name":"gridworks-scada-protocol","ecosystem":"pypi","requirements":"\u003e=1.2.0","direct":true,"kind":"runtime","optional":false},{"id":25800545829,"package_name":"numpy","ecosystem":"pypi","requirements":"\u003e=2.3.3","direct":true,"kind":"runtime","optional":false},{"id":25800545830,"package_name":"paho-mqtt","ecosystem":"pypi","requirements":"\u003e=2.1.0","direct":true,"kind":"runtime","optional":false},{"id":25800545832,"package_name":"pydantic","ecosystem":"pypi","requirements":"\u003e=2.11.9","direct":true,"kind":"runtime","optional":false},{"id":25800545833,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"\u003e=1.1.1","direct":true,"kind":"runtime","optional":false},{"id":25800545834,"package_name":"result","ecosystem":"pypi","requirements":"\u003e=0.9.0","direct":true,"kind":"runtime","optional":false},{"id":25800545835,"package_name":"rich","ecosystem":"pypi","requirements":"\u003e=14.1.0","direct":true,"kind":"runtime","optional":false},{"id":25800545836,"package_name":"textual","ecosystem":"pypi","requirements":"\u003e=6.1.0","direct":true,"kind":"runtime","optional":false},{"id":25800545839,"package_name":"typer","ecosystem":"pypi","requirements":"\u003e=0.17.4","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"pypi","filepath":"packages/gridworks-scada-protocol/pyproject.toml","sha":null,"kind":"manifest","created_at":"2026-01-20T13:07:05.005Z","updated_at":"2026-01-20T13:07:05.005Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/packages/gridworks-scada-protocol/pyproject.toml","dependencies":[{"id":25800545894,"package_name":"gridworks-protocol","ecosystem":"pypi","requirements":"\u003e=1.3.3,\u003c2.0.0","direct":true,"kind":"runtime","optional":false},{"id":25800545896,"package_name":"transitions","ecosystem":"pypi","requirements":"\u003e=0.9.3","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"pypi","filepath":"packages/gridworks-admin/uv.lock","sha":null,"kind":"lockfile","created_at":"2026-01-20T13:07:04.665Z","updated_at":"2026-01-20T13:07:04.665Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/packages/gridworks-admin/uv.lock","dependencies":[{"id":25800545843,"package_name":"aiohappyeyeballs","ecosystem":"pypi","requirements":"2.6.1","direct":false,"kind":"runtime","optional":false},{"id":25800545845,"package_name":"aiohttp","ecosystem":"pypi","requirements":"3.12.15","direct":false,"kind":"runtime","optional":false},{"id":25800545846,"package_name":"aiosignal","ecosystem":"pypi","requirements":"1.4.0","direct":false,"kind":"runtime","optional":false},{"id":25800545847,"package_name":"annotated-types","ecosystem":"pypi","requirements":"0.7.0","direct":false,"kind":"runtime","optional":false},{"id":25800545848,"package_name":"attrs","ecosystem":"pypi","requirements":"25.3.0","direct":false,"kind":"runtime","optional":false},{"id":25800545849,"package_name":"click","ecosystem":"pypi","requirements":"8.2.1","direct":false,"kind":"runtime","optional":false},{"id":25800545850,"package_name":"colorama","ecosystem":"pypi","requirements":"0.4.6","direct":false,"kind":"runtime","optional":false},{"id":25800545851,"package_name":"frozenlist","ecosystem":"pypi","requirements":"1.7.0","direct":false,"kind":"runtime","optional":false},{"id":25800545852,"package_name":"gridworks","ecosystem":"pypi","requirements":"1.5.6","direct":false,"kind":"runtime","optional":false},{"id":25800545853,"package_name":"gridworks-admin","ecosystem":"pypi","requirements":"1.0.8","direct":false,"kind":"runtime","optional":false},{"id":25800545854,"package_name":"gridworks-proactor","ecosystem":"pypi","requirements":"4.1.9","direct":false,"kind":"runtime","optional":false},{"id":25800545855,"package_name":"gridworks-protocol","ecosystem":"pypi","requirements":"1.3.3","direct":false,"kind":"runtime","optional":false},{"id":25800545856,"package_name":"gridworks-scada-protocol","ecosystem":"pypi","requirements":"1.1.1","direct":false,"kind":"runtime","optional":false},{"id":25800545857,"package_name":"idna","ecosystem":"pypi","requirements":"3.10","direct":false,"kind":"runtime","optional":false},{"id":25800545858,"package_name":"linkify-it-py","ecosystem":"pypi","requirements":"2.0.3","direct":false,"kind":"runtime","optional":false},{"id":25800545859,"package_name":"markdown-it-py","ecosystem":"pypi","requirements":"4.0.0","direct":false,"kind":"runtime","optional":false},{"id":25800545860,"package_name":"mdit-py-plugins","ecosystem":"pypi","requirements":"0.5.0","direct":false,"kind":"runtime","optional":false},{"id":25800545861,"package_name":"mdurl","ecosystem":"pypi","requirements":"0.1.2","direct":false,"kind":"runtime","optional":false},{"id":25800545862,"package_name":"multidict","ecosystem":"pypi","requirements":"6.6.4","direct":false,"kind":"runtime","optional":false},{"id":25800545863,"package_name":"numpy","ecosystem":"pypi","requirements":"2.3.3","direct":false,"kind":"runtime","optional":false},{"id":25800545864,"package_name":"paho-mqtt","ecosystem":"pypi","requirements":"2.1.0","direct":false,"kind":"runtime","optional":false},{"id":25800545865,"package_name":"platformdirs","ecosystem":"pypi","requirements":"4.4.0","direct":false,"kind":"runtime","optional":false},{"id":25800545866,"package_name":"propcache","ecosystem":"pypi","requirements":"0.3.2","direct":false,"kind":"runtime","optional":false},{"id":25800545867,"package_name":"pydantic","ecosystem":"pypi","requirements":"2.11.9","direct":false,"kind":"runtime","optional":false},{"id":25800545868,"package_name":"pydantic-core","ecosystem":"pypi","requirements":"2.33.2","direct":false,"kind":"runtime","optional":false},{"id":25800545869,"package_name":"pydantic-extra-types","ecosystem":"pypi","requirements":"2.10.5","direct":false,"kind":"runtime","optional":false},{"id":25800545871,"package_name":"pydantic-settings","ecosystem":"pypi","requirements":"2.10.1","direct":false,"kind":"runtime","optional":false},{"id":25800545872,"package_name":"pygments","ecosystem":"pypi","requirements":"2.19.2","direct":false,"kind":"runtime","optional":false},{"id":25800545873,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"1.1.1","direct":false,"kind":"runtime","optional":false},{"id":25800545874,"package_name":"pytz","ecosystem":"pypi","requirements":"2024.2","direct":false,"kind":"runtime","optional":false},{"id":25800545875,"package_name":"result","ecosystem":"pypi","requirements":"0.9.0","direct":false,"kind":"runtime","optional":false},{"id":25800545876,"package_name":"rich","ecosystem":"pypi","requirements":"14.1.0","direct":false,"kind":"runtime","optional":false},{"id":25800545877,"package_name":"shellingham","ecosystem":"pypi","requirements":"1.5.4","direct":false,"kind":"runtime","optional":false},{"id":25800545878,"package_name":"six","ecosystem":"pypi","requirements":"1.17.0","direct":false,"kind":"runtime","optional":false},{"id":25800545879,"package_name":"textual","ecosystem":"pypi","requirements":"6.1.0","direct":false,"kind":"runtime","optional":false},{"id":25800545880,"package_name":"transitions","ecosystem":"pypi","requirements":"0.9.3","direct":false,"kind":"runtime","optional":false},{"id":25800545881,"package_name":"typer","ecosystem":"pypi","requirements":"0.17.4","direct":false,"kind":"runtime","optional":false},{"id":25800545882,"package_name":"typing-extensions","ecosystem":"pypi","requirements":"4.15.0","direct":false,"kind":"runtime","optional":false},{"id":25800545883,"package_name":"typing-inspection","ecosystem":"pypi","requirements":"0.4.1","direct":false,"kind":"runtime","optional":false},{"id":25800545884,"package_name":"uc-micro-py","ecosystem":"pypi","requirements":"1.0.3","direct":false,"kind":"runtime","optional":false},{"id":25800545889,"package_name":"xdg","ecosystem":"pypi","requirements":"6.0.0","direct":false,"kind":"runtime","optional":false},{"id":25800545891,"package_name":"yarl","ecosystem":"pypi","requirements":"1.20.1","direct":false,"kind":"runtime","optional":false}]},{"ecosystem":"pypi","filepath":"packages/gridworks-scada-protocol/uv.lock","sha":null,"kind":"lockfile","created_at":"2026-01-20T13:07:05.157Z","updated_at":"2026-01-20T13:07:05.157Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/packages/gridworks-scada-protocol/uv.lock","dependencies":[{"id":25800545901,"package_name":"idna","ecosystem":"pypi","requirements":"3.10","direct":false,"kind":"runtime","optional":false},{"id":25800545902,"package_name":"multidict","ecosystem":"pypi","requirements":"6.6.4","direct":false,"kind":"runtime","optional":false},{"id":25800545908,"package_name":"propcache","ecosystem":"pypi","requirements":"0.3.2","direct":false,"kind":"runtime","optional":false},{"id":25800545909,"package_name":"pydantic","ecosystem":"pypi","requirements":"2.11.9","direct":false,"kind":"runtime","optional":false},{"id":25800545910,"package_name":"pydantic-core","ecosystem":"pypi","requirements":"2.33.2","direct":false,"kind":"runtime","optional":false},{"id":25800545911,"package_name":"pydantic-extra-types","ecosystem":"pypi","requirements":"2.10.5","direct":false,"kind":"runtime","optional":false},{"id":25800545912,"package_name":"python-dotenv","ecosystem":"pypi","requirements":"1.1.1","direct":false,"kind":"runtime","optional":false},{"id":25800545913,"package_name":"pytz","ecosystem":"pypi","requirements":"2024.2","direct":false,"kind":"runtime","optional":false},{"id":25800545914,"package_name":"six","ecosystem":"pypi","requirements":"1.17.0","direct":false,"kind":"runtime","optional":false},{"id":25800545915,"package_name":"transitions","ecosystem":"pypi","requirements":"0.9.3","direct":false,"kind":"runtime","optional":false},{"id":25800545916,"package_name":"typing-extensions","ecosystem":"pypi","requirements":"4.15.0","direct":false,"kind":"runtime","optional":false},{"id":25800545917,"package_name":"typing-inspection","ecosystem":"pypi","requirements":"0.4.1","direct":false,"kind":"runtime","optional":false},{"id":25800545918,"package_name":"yarl","ecosystem":"pypi","requirements":"1.20.1","direct":false,"kind":"runtime","optional":false},{"id":25800545897,"package_name":"annotated-types","ecosystem":"pypi","requirements":"0.7.0","direct":false,"kind":"runtime","optional":false},{"id":25800545898,"package_name":"gridworks","ecosystem":"pypi","requirements":"1.5.6","direct":false,"kind":"runtime","optional":false},{"id":25800545899,"package_name":"gridworks-protocol","ecosystem":"pypi","requirements":"1.3.0","direct":false,"kind":"runtime","optional":false},{"id":25800545900,"package_name":"gridworks-scada-protocol","ecosystem":"pypi","requirements":"1.0.1","direct":false,"kind":"runtime","optional":false}]},{"ecosystem":"pypi","filepath":"pyproject.toml","sha":null,"kind":"manifest","created_at":"2024-01-03T20:25:12.864Z","updated_at":"2024-01-03T20:25:12.864Z","repository_link":"https://github.com/thegridelectric/gridworks-scada/blob/dev/pyproject.toml","dependencies":[]}],"score":5.762051382780177,"created_at":"2024-04-26T00:04:14.207Z","updated_at":"2026-05-15T23:30:22.121Z","avatar_url":"https://github.com/thegridelectric.png","language":"Python","category":"Consumption","sub_category":"Buildings and Heating","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"# GridWorks SCADA\n\n[![Tests](https://github.com/thegridelectric/gridworks-scada/actions/workflows/ci.yaml/badge.svg)][tests]\n[![Codecov](https://codecov.io/gh/thegridelectric/gridworks-scada/branch/main/graph/badge.svg)][codecov]\n\n[tests]: https://github.com/thegridelectric/gridworks-scada/actions/workflows/ci.yaml\n[codecov]: https://app.codecov.io/gh/thegridelectric/gridworks-scada\n========\n\n\nThis repository is for GridWorks contributors developing SCADA software for transactive heat pump thermal storage systems.\n\nThe software runs residential heat-pump-based space-heating systems with thermal storage and coordinates operation with electric grid conditions. In practice, that means shifting energy use toward lower-cost or grid-favorable times while maintaining occupant comfort.\n\nThis repository is part of a larger GridWorks framework. It typically operates alongside a cloud-based actor called the **LeafTransactiveNode**, which provides higher-level dispatch and coordination. Internally, the code follows an actor-based architecture: many focused components communicate through messages, with each actor responsible for a limited operational domain.\n\nThis project is funded by Efficiency Maine.\n\n\n## Quick Start\n\n\nFor most contributors:\n\n1. **Start with the Testing section.** For many small changes, running tests locally is enough.\n2. **Run SCADA locally with `.env` if needed.** This is useful when debugging runtime behavior or configuration issues.\n3. **Use RabbitMQ only for integration scenarios.** This is typically needed when simulating upstream GridWorks/cloud behavior or multi-process local environments.\n\n## Testing\n\n\n  1. **Start the local test mosquitto broker** Run from the repo root:\n\n    mosquitto -c tests/config/local_mosquitto.conf -v \u0026\n\n\u003e If you already run Mosquitto through Homebrew as a background service, stop that first so ports are not already in use.\n\n 2. **Create venv**: Run `./tools/mkenv.sh`.  This creates `gw_spaceheat/venv/`\n    - (On a Raspberry Pi use `./tools/mkenv-pi.sh`.)\n 3.  **Activate venv**:  `source gw_spaceheat/venv/bin/activate`\n 4.  **Export pythonpath**: include gw_spaceheat in the pythonpath\n     - Linux/mac: `export PYTHONPATH=[PATH TO]/gridworks-scada/gw_spaceheat:$PYTHONPATH`\n     - Windows in powershell: $env:PYTHONPATH=\"C:\\Users\\Joe\\Coding\\gridworks-scada\\gw_spaceheat;$env:PYTHONPATH\"\n 5. **Run tests:** `pytest -v`\n\n### Test Environment Notes\n\nAlthough the larger GridWorks ecosystem uses message-passing through a RabbitMQ broker, **SCADA-only development and pytest runs do not require RabbitMQ**.\n\nThe SCADA process conceptually talks to two MQTT brokers:\n\n- **upstream / gridworks_mqtt** — normally the cloud-side GridWorks broker\n- **local / local_mqtt** — the LAN-side broker used for local actors such as SCADA2\n\nFor local testing, both are replaced with a simple cleartext Mosquitto setup.\n\nTests assume a local MQTT broker with an **upstream broker** at `localhost:1883`\nand a **local/downstream broker** at `localhost:18831`.\n\n### Optional Shell Alias\n\n```\n    alias gw=\"source $HOME/Coding/gridworks-scada/gw_spaceheat/venv/bin/activate \\\n    \u0026\u0026 cd $HOME/Coding/gridworks-scada \\\n    \u0026\u0026 export PYTHONPATH=$HOME/Coding/gridworks-scada/gw_spaceheat:$PYTHONPATH\"\n```\n### Test Bootstrap Behavior\n\n`pytest` automatically uses repo-owned local defaults from:\n\n- `tests/config/.env-local`\n- `tests/config/hardware-layout.json`\n\nYour normal `.env` file is **not** used during pytest unless a specific test explicitly opts into it.\n\n### CI Testing\n\nThe CI workflow uses a different broker/certificate setup in\n[`.github/workflows/ci.yaml`](.github/workflows/ci.yaml). It uses a separate broker/certificate setup and exercises TLS paths.\n\nIf you need to understand or regenerate the test CA, broker certs, or client certs,\nlook at the [`gridworks-cert`](https://github.com/thegridelectric/gridworks-cert/README.md) repo first. This\nrepository relies on `gwcert` conventions and test CA paths from that toolchain.\n\n\n## CLI\n\nSCADA includes a lightweight command-line tool called `gws` that is useful for both development and production tasks.\n\n### Install the CLI\n\n\n    ./tools/install-gws.sh\n\n### Common Commands\n\nShow the current resolved configuration:\n\n    gws config\n\nThis is often the fastest way to verify paths, environment variables, and active settings. For example:\n\n    hardware_layout=PosixPath('[HOME]/.config/gridworks/scada/hardware-layout.json')\n\nPreview what SCADA would do without starting it:\n\n    gws run --dry-run\n\nStart SCADA locally:\n\n    gws run\n\n\n\n### Practical Use\n\nDuring development, `gws config` and `gws run --dry-run` are especially useful for confirming that your hardware layout, `.env`, and local broker settings are being picked up correctly.\n\n## Running SCADA Locally with `.env`\n\nScada is designed to operate with a `.env` variable and a hardware layout.  You\nmay choose to use these while running locally. Be aware that they are NOT used in tests.\n\n\nFor development purposes I recommend updating the hardware layout location in your local `.env` file. To do this for the first time , **copy the existing `.env-template` over to `.env`. Then rerun `gws config` and confirm that the  layout is now `tests/config/hardware-layout.json`.\n\n\n### Creating your own dev hardware layout\n  \nIn a sibling directory clone the [tlayouts](https://github.com/thegridelectric/tlayouts) directory. Then: \n\n - While in the virtual env for this repository, navigate to `tlayouts`.\n - Run `gen_orange.py`\n\nThis will generate a simulated hardware layout in `outputs/orange.generated.json` \n - Update your `.env` to include:\n\n```\nSCADA_PATHS__HARDWARE_LAYOUT=\"../tlayouts/output/orange.generated.json\"\nLTN_PATHS__HARDWARE_LAYOUT=\"../tlayouts/output/orange.generated.json\"\n```\n\n### Dependencies\n\nAdd package requirements in:\n\n- `gw_spaceheat/requirements/dev.in` — development / CI\n- `gw_spaceheat/requirements/drivers.in` — Raspberry Pi only\n- `gw_spaceheat/requirements/base.in` — all environments\n\nThen run:\n\n    tools/pipc.sh\n\n## Advanced: Using RabbitMQ for Multi-Repo Integration\n\nIf you want to do cross-repo tests you may want to use the dev rabbit broker  at   [https://github.com/thegridelectric/gridworks-base?tab=readme-ov-file#dev-rabbit-broker](https://github.com/thegridelectric/gridworks-base?tab=readme-ov-file#dev-rabbit-broker).  Follow instructions there. \n\nRabbitMQ must expose its MQTT plugin so SCADA can connect using MQTT. Three steps for getting the docker rabbit instance to enable mqtt:\n```\ndocker exec -it gw-dev-rabbit rabbitmq-plugins enable rabbitmq_mqtt\ndocker exec -it gw-dev-rabbit rabbitmqctl restart_app\ndocker exec -it gw-dev-rabbit rabbitmq-plugins list\n```\n\nAnd confirm:\n [E*] rabbitmq_mqtt                     3.9.13\n\n(Troubleshooting how to get this into the docker yaml file over in gridworks-base)\n\nTest mqtt access via mqtt_sub:\n\n```\nmosquitto_sub -h localhost -p 1885 -u smqPublic -P smqPublic -t \"#\" -v\n```\n\nShould see an `mqtt-subscription-XXX` show up on the rabbit admin panel http://localhost:15672/#/queues.\n\n\n### Linting\n\nRun:\n\n```shell\nruff check\n```\n\nRuff is advisory today and does not yet pass.\n\n\n\n\n## Admin\n\nInstall:\n\n    uv tool install gridworks-admin\n\nUpdate: \n\n    uv tool update gridworks-admin\n\nRun locally:\n\n    gwa watch\n\n\nSee the [packages directory README.md](./packages/README.md) for more information.\n\n\n\n## Raspberry Pi Service\n\nInstall:\n\n    ./service/install\n\nStatus:\n\n    gwstatus\n\nStart:\n\n    gwstart\n\nPause:\n\n    gwpause\n\nStop:\n\n    gwstop\n\n\n## Additional Documentation\n\nFor deployment, TLS, and editor setup details, see:\n\n- `docs/tls.md`\n- `docs/provisioning.md`\n- `docs/editor-setup.md`\n\n## License\n\nDistributed under the terms of the [MIT license](./LICENSE),\nthis repository is free and open source software.\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":[],"project_url":"https://ost.ecosyste.ms/api/v1/projects/191736","html_url":"https://ost.ecosyste.ms/projects/191736"}